Branch data Line data Source code
1 : : /* Global, SSA-based optimizations using mathematical identities.
2 : : Copyright (C) 2005-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it
7 : : under the terms of the GNU General Public License as published by the
8 : : Free Software Foundation; either version 3, or (at your option) any
9 : : later version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT
12 : : ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : /* Currently, the only mini-pass in this file tries to CSE reciprocal
21 : : operations. These are common in sequences such as this one:
22 : :
23 : : modulus = sqrt(x*x + y*y + z*z);
24 : : x = x / modulus;
25 : : y = y / modulus;
26 : : z = z / modulus;
27 : :
28 : : that can be optimized to
29 : :
30 : : modulus = sqrt(x*x + y*y + z*z);
31 : : rmodulus = 1.0 / modulus;
32 : : x = x * rmodulus;
33 : : y = y * rmodulus;
34 : : z = z * rmodulus;
35 : :
36 : : We do this for loop invariant divisors, and with this pass whenever
37 : : we notice that a division has the same divisor multiple times.
38 : :
39 : : Of course, like in PRE, we don't insert a division if a dominator
40 : : already has one. However, this cannot be done as an extension of
41 : : PRE for several reasons.
42 : :
43 : : First of all, with some experiments it was found out that the
44 : : transformation is not always useful if there are only two divisions
45 : : by the same divisor. This is probably because modern processors
46 : : can pipeline the divisions; on older, in-order processors it should
47 : : still be effective to optimize two divisions by the same number.
48 : : We make this a param, and it shall be called N in the remainder of
49 : : this comment.
50 : :
51 : : Second, if trapping math is active, we have less freedom on where
52 : : to insert divisions: we can only do so in basic blocks that already
53 : : contain one. (If divisions don't trap, instead, we can insert
54 : : divisions elsewhere, which will be in blocks that are common dominators
55 : : of those that have the division).
56 : :
57 : : We really don't want to compute the reciprocal unless a division will
58 : : be found. To do this, we won't insert the division in a basic block
59 : : that has less than N divisions *post-dominating* it.
60 : :
61 : : The algorithm constructs a subset of the dominator tree, holding the
62 : : blocks containing the divisions and the common dominators to them,
63 : : and walk it twice. The first walk is in post-order, and it annotates
64 : : each block with the number of divisions that post-dominate it: this
65 : : gives information on where divisions can be inserted profitably.
66 : : The second walk is in pre-order, and it inserts divisions as explained
67 : : above, and replaces divisions by multiplications.
68 : :
69 : : In the best case, the cost of the pass is O(n_statements). In the
70 : : worst-case, the cost is due to creating the dominator tree subset,
71 : : with a cost of O(n_basic_blocks ^ 2); however this can only happen
72 : : for n_statements / n_basic_blocks statements. So, the amortized cost
73 : : of creating the dominator tree subset is O(n_basic_blocks) and the
74 : : worst-case cost of the pass is O(n_statements * n_basic_blocks).
75 : :
76 : : More practically, the cost will be small because there are few
77 : : divisions, and they tend to be in the same basic block, so insert_bb
78 : : is called very few times.
79 : :
80 : : If we did this using domwalk.cc, an efficient implementation would have
81 : : to work on all the variables in a single pass, because we could not
82 : : work on just a subset of the dominator tree, as we do now, and the
83 : : cost would also be something like O(n_statements * n_basic_blocks).
84 : : The data structures would be more complex in order to work on all the
85 : : variables in a single pass. */
86 : :
87 : : #include "config.h"
88 : : #include "system.h"
89 : : #include "coretypes.h"
90 : : #include "backend.h"
91 : : #include "target.h"
92 : : #include "rtl.h"
93 : : #include "tree.h"
94 : : #include "gimple.h"
95 : : #include "predict.h"
96 : : #include "alloc-pool.h"
97 : : #include "tree-pass.h"
98 : : #include "ssa.h"
99 : : #include "optabs-tree.h"
100 : : #include "gimple-pretty-print.h"
101 : : #include "alias.h"
102 : : #include "fold-const.h"
103 : : #include "gimple-iterator.h"
104 : : #include "gimple-fold.h"
105 : : #include "gimplify.h"
106 : : #include "gimplify-me.h"
107 : : #include "stor-layout.h"
108 : : #include "tree-cfg.h"
109 : : #include "tree-dfa.h"
110 : : #include "tree-ssa.h"
111 : : #include "builtins.h"
112 : : #include "internal-fn.h"
113 : : #include "case-cfn-macros.h"
114 : : #include "optabs-libfuncs.h"
115 : : #include "tree-eh.h"
116 : : #include "targhooks.h"
117 : : #include "domwalk.h"
118 : : #include "tree-ssa-math-opts.h"
119 : : #include "dbgcnt.h"
120 : : #include "cfghooks.h"
121 : :
122 : : /* This structure represents one basic block that either computes a
123 : : division, or is a common dominator for basic block that compute a
124 : : division. */
125 : : struct occurrence {
126 : : /* The basic block represented by this structure. */
127 : : basic_block bb = basic_block();
128 : :
129 : : /* If non-NULL, the SSA_NAME holding the definition for a reciprocal
130 : : inserted in BB. */
131 : : tree recip_def = tree();
132 : :
133 : : /* If non-NULL, the SSA_NAME holding the definition for a squared
134 : : reciprocal inserted in BB. */
135 : : tree square_recip_def = tree();
136 : :
137 : : /* If non-NULL, the GIMPLE_ASSIGN for a reciprocal computation that
138 : : was inserted in BB. */
139 : : gimple *recip_def_stmt = nullptr;
140 : :
141 : : /* Pointer to a list of "struct occurrence"s for blocks dominated
142 : : by BB. */
143 : : struct occurrence *children = nullptr;
144 : :
145 : : /* Pointer to the next "struct occurrence"s in the list of blocks
146 : : sharing a common dominator. */
147 : : struct occurrence *next = nullptr;
148 : :
149 : : /* The number of divisions that are in BB before compute_merit. The
150 : : number of divisions that are in BB or post-dominate it after
151 : : compute_merit. */
152 : : int num_divisions = 0;
153 : :
154 : : /* True if the basic block has a division, false if it is a common
155 : : dominator for basic blocks that do. If it is false and trapping
156 : : math is active, BB is not a candidate for inserting a reciprocal. */
157 : : bool bb_has_division = false;
158 : :
159 : : /* Construct a struct occurrence for basic block BB, and whose
160 : : children list is headed by CHILDREN. */
161 : 594 : occurrence (basic_block bb, struct occurrence *children)
162 : 594 : : bb (bb), children (children)
163 : : {
164 : 594 : bb->aux = this;
165 : : }
166 : :
167 : : /* Destroy a struct occurrence and remove it from its basic block. */
168 : 594 : ~occurrence ()
169 : : {
170 : 594 : bb->aux = nullptr;
171 : 594 : }
172 : :
173 : : /* Allocate memory for a struct occurrence from OCC_POOL. */
174 : : static void* operator new (size_t);
175 : :
176 : : /* Return memory for a struct occurrence to OCC_POOL. */
177 : : static void operator delete (void*, size_t);
178 : : };
179 : :
180 : : static struct
181 : : {
182 : : /* Number of 1.0/X ops inserted. */
183 : : int rdivs_inserted;
184 : :
185 : : /* Number of 1.0/FUNC ops inserted. */
186 : : int rfuncs_inserted;
187 : : } reciprocal_stats;
188 : :
189 : : static struct
190 : : {
191 : : /* Number of cexpi calls inserted. */
192 : : int inserted;
193 : :
194 : : /* Number of conversions removed. */
195 : : int conv_removed;
196 : :
197 : : } sincos_stats;
198 : :
199 : : static struct
200 : : {
201 : : /* Number of widening multiplication ops inserted. */
202 : : int widen_mults_inserted;
203 : :
204 : : /* Number of integer multiply-and-accumulate ops inserted. */
205 : : int maccs_inserted;
206 : :
207 : : /* Number of fp fused multiply-add ops inserted. */
208 : : int fmas_inserted;
209 : :
210 : : /* Number of divmod calls inserted. */
211 : : int divmod_calls_inserted;
212 : :
213 : : /* Number of highpart multiplication ops inserted. */
214 : : int highpart_mults_inserted;
215 : : } widen_mul_stats;
216 : :
217 : : /* The instance of "struct occurrence" representing the highest
218 : : interesting block in the dominator tree. */
219 : : static struct occurrence *occ_head;
220 : :
221 : : /* Allocation pool for getting instances of "struct occurrence". */
222 : : static object_allocator<occurrence> *occ_pool;
223 : :
224 : 594 : void* occurrence::operator new (size_t n)
225 : : {
226 : 594 : gcc_assert (n == sizeof(occurrence));
227 : 594 : return occ_pool->allocate_raw ();
228 : : }
229 : :
230 : 594 : void occurrence::operator delete (void *occ, size_t n)
231 : : {
232 : 594 : gcc_assert (n == sizeof(occurrence));
233 : 594 : occ_pool->remove_raw (occ);
234 : 594 : }
235 : :
236 : : /* Insert NEW_OCC into our subset of the dominator tree. P_HEAD points to a
237 : : list of "struct occurrence"s, one per basic block, having IDOM as
238 : : their common dominator.
239 : :
240 : : We try to insert NEW_OCC as deep as possible in the tree, and we also
241 : : insert any other block that is a common dominator for BB and one
242 : : block already in the tree. */
243 : :
244 : : static void
245 : 582 : insert_bb (struct occurrence *new_occ, basic_block idom,
246 : : struct occurrence **p_head)
247 : : {
248 : 588 : struct occurrence *occ, **p_occ;
249 : :
250 : 614 : for (p_occ = p_head; (occ = *p_occ) != NULL; )
251 : : {
252 : 32 : basic_block bb = new_occ->bb, occ_bb = occ->bb;
253 : 32 : basic_block dom = nearest_common_dominator (CDI_DOMINATORS, occ_bb, bb);
254 : 32 : if (dom == bb)
255 : : {
256 : : /* BB dominates OCC_BB. OCC becomes NEW_OCC's child: remove OCC
257 : : from its list. */
258 : 7 : *p_occ = occ->next;
259 : 7 : occ->next = new_occ->children;
260 : 7 : new_occ->children = occ;
261 : :
262 : : /* Try the next block (it may as well be dominated by BB). */
263 : : }
264 : :
265 : 25 : else if (dom == occ_bb)
266 : : {
267 : : /* OCC_BB dominates BB. Tail recurse to look deeper. */
268 : 6 : insert_bb (new_occ, dom, &occ->children);
269 : 6 : return;
270 : : }
271 : :
272 : 19 : else if (dom != idom)
273 : : {
274 : 12 : gcc_assert (!dom->aux);
275 : :
276 : : /* There is a dominator between IDOM and BB, add it and make
277 : : two children out of NEW_OCC and OCC. First, remove OCC from
278 : : its list. */
279 : 12 : *p_occ = occ->next;
280 : 12 : new_occ->next = occ;
281 : 12 : occ->next = NULL;
282 : :
283 : : /* None of the previous blocks has DOM as a dominator: if we tail
284 : : recursed, we would reexamine them uselessly. Just switch BB with
285 : : DOM, and go on looking for blocks dominated by DOM. */
286 : 12 : new_occ = new occurrence (dom, new_occ);
287 : : }
288 : :
289 : : else
290 : : {
291 : : /* Nothing special, go on with the next element. */
292 : 7 : p_occ = &occ->next;
293 : : }
294 : : }
295 : :
296 : : /* No place was found as a child of IDOM. Make BB a sibling of IDOM. */
297 : 582 : new_occ->next = *p_head;
298 : 582 : *p_head = new_occ;
299 : : }
300 : :
301 : : /* Register that we found a division in BB.
302 : : IMPORTANCE is a measure of how much weighting to give
303 : : that division. Use IMPORTANCE = 2 to register a single
304 : : division. If the division is going to be found multiple
305 : : times use 1 (as it is with squares). */
306 : :
307 : : static inline void
308 : 676 : register_division_in (basic_block bb, int importance)
309 : : {
310 : 676 : struct occurrence *occ;
311 : :
312 : 676 : occ = (struct occurrence *) bb->aux;
313 : 676 : if (!occ)
314 : : {
315 : 582 : occ = new occurrence (bb, NULL);
316 : 582 : insert_bb (occ, ENTRY_BLOCK_PTR_FOR_FN (cfun), &occ_head);
317 : : }
318 : :
319 : 676 : occ->bb_has_division = true;
320 : 676 : occ->num_divisions += importance;
321 : 676 : }
322 : :
323 : :
324 : : /* Compute the number of divisions that postdominate each block in OCC and
325 : : its children. */
326 : :
327 : : static void
328 : 31 : compute_merit (struct occurrence *occ)
329 : : {
330 : 31 : struct occurrence *occ_child;
331 : 31 : basic_block dom = occ->bb;
332 : :
333 : 60 : for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
334 : : {
335 : 29 : basic_block bb;
336 : 29 : if (occ_child->children)
337 : 5 : compute_merit (occ_child);
338 : :
339 : 29 : if (flag_exceptions)
340 : 6 : bb = single_noncomplex_succ (dom);
341 : : else
342 : : bb = dom;
343 : :
344 : 29 : if (dominated_by_p (CDI_POST_DOMINATORS, bb, occ_child->bb))
345 : 12 : occ->num_divisions += occ_child->num_divisions;
346 : : }
347 : 31 : }
348 : :
349 : :
350 : : /* Return whether USE_STMT is a floating-point division by DEF. */
351 : : static inline bool
352 : 359037 : is_division_by (gimple *use_stmt, tree def)
353 : : {
354 : 359037 : return is_gimple_assign (use_stmt)
355 : 241228 : && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
356 : 1233 : && gimple_assign_rhs2 (use_stmt) == def
357 : : /* Do not recognize x / x as valid division, as we are getting
358 : : confused later by replacing all immediate uses x in such
359 : : a stmt. */
360 : 853 : && gimple_assign_rhs1 (use_stmt) != def
361 : 359890 : && !stmt_can_throw_internal (cfun, use_stmt);
362 : : }
363 : :
364 : : /* Return TRUE if USE_STMT is a multiplication of DEF by A. */
365 : : static inline bool
366 : 355356 : is_mult_by (gimple *use_stmt, tree def, tree a)
367 : : {
368 : 355356 : if (gimple_code (use_stmt) == GIMPLE_ASSIGN
369 : 355356 : && gimple_assign_rhs_code (use_stmt) == MULT_EXPR)
370 : : {
371 : 78169 : tree op0 = gimple_assign_rhs1 (use_stmt);
372 : 78169 : tree op1 = gimple_assign_rhs2 (use_stmt);
373 : :
374 : 78169 : return (op0 == def && op1 == a)
375 : 78169 : || (op0 == a && op1 == def);
376 : : }
377 : : return 0;
378 : : }
379 : :
380 : : /* Return whether USE_STMT is DEF * DEF. */
381 : : static inline bool
382 : 355311 : is_square_of (gimple *use_stmt, tree def)
383 : : {
384 : 5 : return is_mult_by (use_stmt, def, def);
385 : : }
386 : :
387 : : /* Return whether USE_STMT is a floating-point division by
388 : : DEF * DEF. */
389 : : static inline bool
390 : 181 : is_division_by_square (gimple *use_stmt, tree def)
391 : : {
392 : 181 : if (gimple_code (use_stmt) == GIMPLE_ASSIGN
393 : 174 : && gimple_assign_rhs_code (use_stmt) == RDIV_EXPR
394 : 7 : && gimple_assign_rhs1 (use_stmt) != gimple_assign_rhs2 (use_stmt)
395 : 188 : && !stmt_can_throw_internal (cfun, use_stmt))
396 : : {
397 : 7 : tree denominator = gimple_assign_rhs2 (use_stmt);
398 : 7 : if (TREE_CODE (denominator) == SSA_NAME)
399 : 7 : return is_square_of (SSA_NAME_DEF_STMT (denominator), def);
400 : : }
401 : : return 0;
402 : : }
403 : :
404 : : /* Walk the subset of the dominator tree rooted at OCC, setting the
405 : : RECIP_DEF field to a definition of 1.0 / DEF that can be used in
406 : : the given basic block. The field may be left NULL, of course,
407 : : if it is not possible or profitable to do the optimization.
408 : :
409 : : DEF_BSI is an iterator pointing at the statement defining DEF.
410 : : If RECIP_DEF is set, a dominator already has a computation that can
411 : : be used.
412 : :
413 : : If should_insert_square_recip is set, then this also inserts
414 : : the square of the reciprocal immediately after the definition
415 : : of the reciprocal. */
416 : :
417 : : static void
418 : 55 : insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ,
419 : : tree def, tree recip_def, tree square_recip_def,
420 : : int should_insert_square_recip, int threshold)
421 : : {
422 : 55 : tree type;
423 : 55 : gassign *new_stmt, *new_square_stmt;
424 : 55 : gimple_stmt_iterator gsi;
425 : 55 : struct occurrence *occ_child;
426 : :
427 : 55 : if (!recip_def
428 : 39 : && (occ->bb_has_division || !flag_trapping_math)
429 : : /* Divide by two as all divisions are counted twice in
430 : : the costing loop. */
431 : 35 : && occ->num_divisions / 2 >= threshold)
432 : : {
433 : : /* Make a variable with the replacement and substitute it. */
434 : 24 : type = TREE_TYPE (def);
435 : 24 : recip_def = create_tmp_reg (type, "reciptmp");
436 : 24 : new_stmt = gimple_build_assign (recip_def, RDIV_EXPR,
437 : : build_one_cst (type), def);
438 : :
439 : 24 : if (should_insert_square_recip)
440 : : {
441 : 4 : square_recip_def = create_tmp_reg (type, "powmult_reciptmp");
442 : 4 : new_square_stmt = gimple_build_assign (square_recip_def, MULT_EXPR,
443 : : recip_def, recip_def);
444 : : }
445 : :
446 : 24 : if (occ->bb_has_division)
447 : : {
448 : : /* Case 1: insert before an existing division. */
449 : 21 : gsi = gsi_after_labels (occ->bb);
450 : 201 : while (!gsi_end_p (gsi)
451 : 201 : && (!is_division_by (gsi_stmt (gsi), def))
452 : 382 : && (!is_division_by_square (gsi_stmt (gsi), def)))
453 : 180 : gsi_next (&gsi);
454 : :
455 : 21 : gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
456 : 21 : if (should_insert_square_recip)
457 : 3 : gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
458 : : }
459 : 3 : else if (def_gsi && occ->bb == gsi_bb (*def_gsi))
460 : : {
461 : : /* Case 2: insert right after the definition. Note that this will
462 : : never happen if the definition statement can throw, because in
463 : : that case the sole successor of the statement's basic block will
464 : : dominate all the uses as well. */
465 : 2 : gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
466 : 2 : if (should_insert_square_recip)
467 : 1 : gsi_insert_after (def_gsi, new_square_stmt, GSI_NEW_STMT);
468 : : }
469 : : else
470 : : {
471 : : /* Case 3: insert in a basic block not containing defs/uses. */
472 : 1 : gsi = gsi_after_labels (occ->bb);
473 : 1 : gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
474 : 1 : if (should_insert_square_recip)
475 : 0 : gsi_insert_before (&gsi, new_square_stmt, GSI_SAME_STMT);
476 : : }
477 : :
478 : 24 : reciprocal_stats.rdivs_inserted++;
479 : :
480 : 24 : occ->recip_def_stmt = new_stmt;
481 : : }
482 : :
483 : 55 : occ->recip_def = recip_def;
484 : 55 : occ->square_recip_def = square_recip_def;
485 : 84 : for (occ_child = occ->children; occ_child; occ_child = occ_child->next)
486 : 29 : insert_reciprocals (def_gsi, occ_child, def, recip_def,
487 : : square_recip_def, should_insert_square_recip,
488 : : threshold);
489 : 55 : }
490 : :
491 : : /* Replace occurrences of expr / (x * x) with expr * ((1 / x) * (1 / x)).
492 : : Take as argument the use for (x * x). */
493 : : static inline void
494 : 4 : replace_reciprocal_squares (use_operand_p use_p)
495 : : {
496 : 4 : gimple *use_stmt = USE_STMT (use_p);
497 : 4 : basic_block bb = gimple_bb (use_stmt);
498 : 4 : struct occurrence *occ = (struct occurrence *) bb->aux;
499 : :
500 : 8 : if (optimize_bb_for_speed_p (bb) && occ->square_recip_def
501 : 8 : && occ->recip_def)
502 : : {
503 : 4 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
504 : 4 : gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
505 : 4 : gimple_assign_set_rhs2 (use_stmt, occ->square_recip_def);
506 : 4 : SET_USE (use_p, occ->square_recip_def);
507 : 4 : fold_stmt_inplace (&gsi);
508 : 4 : update_stmt (use_stmt);
509 : : }
510 : 4 : }
511 : :
512 : :
513 : : /* Replace the division at USE_P with a multiplication by the reciprocal, if
514 : : possible. */
515 : :
516 : : static inline void
517 : 115 : replace_reciprocal (use_operand_p use_p)
518 : : {
519 : 115 : gimple *use_stmt = USE_STMT (use_p);
520 : 115 : basic_block bb = gimple_bb (use_stmt);
521 : 115 : struct occurrence *occ = (struct occurrence *) bb->aux;
522 : :
523 : 115 : if (optimize_bb_for_speed_p (bb)
524 : 115 : && occ->recip_def && use_stmt != occ->recip_def_stmt)
525 : : {
526 : 80 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
527 : 80 : gimple_assign_set_rhs_code (use_stmt, MULT_EXPR);
528 : 80 : SET_USE (use_p, occ->recip_def);
529 : 80 : fold_stmt_inplace (&gsi);
530 : 80 : update_stmt (use_stmt);
531 : : }
532 : 115 : }
533 : :
534 : :
535 : : /* Free OCC and return one more "struct occurrence" to be freed. */
536 : :
537 : : static struct occurrence *
538 : 594 : free_bb (struct occurrence *occ)
539 : : {
540 : 594 : struct occurrence *child, *next;
541 : :
542 : : /* First get the two pointers hanging off OCC. */
543 : 594 : next = occ->next;
544 : 594 : child = occ->children;
545 : 594 : delete occ;
546 : :
547 : : /* Now ensure that we don't recurse unless it is necessary. */
548 : 594 : if (!child)
549 : : return next;
550 : : else
551 : : {
552 : 24 : while (next)
553 : 3 : next = free_bb (next);
554 : :
555 : : return child;
556 : : }
557 : : }
558 : :
559 : : /* Transform sequences like
560 : : t = sqrt (a)
561 : : x = 1.0 / t;
562 : : r1 = x * x;
563 : : r2 = a * x;
564 : : into:
565 : : t = sqrt (a)
566 : : r1 = 1.0 / a;
567 : : r2 = t;
568 : : x = r1 * r2;
569 : : depending on the uses of x, r1, r2. This removes one multiplication and
570 : : allows the sqrt and division operations to execute in parallel.
571 : : DEF_GSI is the gsi of the initial division by sqrt that defines
572 : : DEF (x in the example above). */
573 : :
574 : : static void
575 : 538 : optimize_recip_sqrt (gimple_stmt_iterator *def_gsi, tree def)
576 : : {
577 : 538 : gimple *use_stmt;
578 : 538 : imm_use_iterator use_iter;
579 : 538 : gimple *stmt = gsi_stmt (*def_gsi);
580 : 538 : tree x = def;
581 : 538 : tree orig_sqrt_ssa_name = gimple_assign_rhs2 (stmt);
582 : 538 : tree div_rhs1 = gimple_assign_rhs1 (stmt);
583 : :
584 : 538 : if (TREE_CODE (orig_sqrt_ssa_name) != SSA_NAME
585 : 533 : || TREE_CODE (div_rhs1) != REAL_CST
586 : 706 : || !real_equal (&TREE_REAL_CST (div_rhs1), &dconst1))
587 : 447 : return;
588 : :
589 : 91 : gcall *sqrt_stmt
590 : 568 : = dyn_cast <gcall *> (SSA_NAME_DEF_STMT (orig_sqrt_ssa_name));
591 : :
592 : 42 : if (!sqrt_stmt || !gimple_call_lhs (sqrt_stmt))
593 : : return;
594 : :
595 : 42 : switch (gimple_call_combined_fn (sqrt_stmt))
596 : : {
597 : 31 : CASE_CFN_SQRT:
598 : 31 : CASE_CFN_SQRT_FN:
599 : 31 : break;
600 : :
601 : : default:
602 : : return;
603 : : }
604 : 31 : tree a = gimple_call_arg (sqrt_stmt, 0);
605 : :
606 : : /* We have 'a' and 'x'. Now analyze the uses of 'x'. */
607 : :
608 : : /* Statements that use x in x * x. */
609 : 43 : auto_vec<gimple *> sqr_stmts;
610 : : /* Statements that use x in a * x. */
611 : 12 : auto_vec<gimple *> mult_stmts;
612 : 31 : bool has_other_use = false;
613 : 31 : bool mult_on_main_path = false;
614 : :
615 : 89 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, x)
616 : : {
617 : 58 : if (is_gimple_debug (use_stmt))
618 : 1 : continue;
619 : 57 : if (is_square_of (use_stmt, x))
620 : : {
621 : 12 : sqr_stmts.safe_push (use_stmt);
622 : 12 : if (gimple_bb (use_stmt) == gimple_bb (stmt))
623 : 17 : mult_on_main_path = true;
624 : : }
625 : 45 : else if (is_mult_by (use_stmt, x, a))
626 : : {
627 : 14 : mult_stmts.safe_push (use_stmt);
628 : 14 : if (gimple_bb (use_stmt) == gimple_bb (stmt))
629 : 17 : mult_on_main_path = true;
630 : : }
631 : : else
632 : : has_other_use = true;
633 : 31 : }
634 : :
635 : : /* In the x * x and a * x cases we just rewire stmt operands or
636 : : remove multiplications. In the has_other_use case we introduce
637 : : a multiplication so make sure we don't introduce a multiplication
638 : : on a path where there was none. */
639 : 31 : if (has_other_use && !mult_on_main_path)
640 : 19 : return;
641 : :
642 : 12 : if (sqr_stmts.is_empty () && mult_stmts.is_empty ())
643 : : return;
644 : :
645 : : /* If x = 1.0 / sqrt (a) has uses other than those optimized here we want
646 : : to be able to compose it from the sqr and mult cases. */
647 : 41 : if (has_other_use && (sqr_stmts.is_empty () || mult_stmts.is_empty ()))
648 : : return;
649 : :
650 : 12 : if (dump_file)
651 : : {
652 : 10 : fprintf (dump_file, "Optimizing reciprocal sqrt multiplications of\n");
653 : 10 : print_gimple_stmt (dump_file, sqrt_stmt, 0, TDF_NONE);
654 : 10 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
655 : 10 : fprintf (dump_file, "\n");
656 : : }
657 : :
658 : 12 : bool delete_div = !has_other_use;
659 : 12 : tree sqr_ssa_name = NULL_TREE;
660 : 12 : if (!sqr_stmts.is_empty ())
661 : : {
662 : : /* r1 = x * x. Transform the original
663 : : x = 1.0 / t
664 : : into
665 : : tmp1 = 1.0 / a
666 : : r1 = tmp1. */
667 : :
668 : 10 : sqr_ssa_name
669 : 10 : = make_temp_ssa_name (TREE_TYPE (a), NULL, "recip_sqrt_sqr");
670 : :
671 : 10 : if (dump_file)
672 : : {
673 : 10 : fprintf (dump_file, "Replacing original division\n");
674 : 10 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
675 : 10 : fprintf (dump_file, "with new division\n");
676 : : }
677 : 10 : stmt
678 : 10 : = gimple_build_assign (sqr_ssa_name, gimple_assign_rhs_code (stmt),
679 : : gimple_assign_rhs1 (stmt), a);
680 : 10 : gsi_insert_before (def_gsi, stmt, GSI_SAME_STMT);
681 : 10 : gsi_remove (def_gsi, true);
682 : 10 : *def_gsi = gsi_for_stmt (stmt);
683 : 10 : fold_stmt_inplace (def_gsi);
684 : 10 : update_stmt (stmt);
685 : :
686 : 10 : if (dump_file)
687 : 10 : print_gimple_stmt (dump_file, stmt, 0, TDF_NONE);
688 : :
689 : 20 : delete_div = false;
690 : : gimple *sqr_stmt;
691 : : unsigned int i;
692 : 20 : FOR_EACH_VEC_ELT (sqr_stmts, i, sqr_stmt)
693 : : {
694 : 10 : gimple_stmt_iterator gsi2 = gsi_for_stmt (sqr_stmt);
695 : 10 : gimple_assign_set_rhs_from_tree (&gsi2, sqr_ssa_name);
696 : 10 : update_stmt (sqr_stmt);
697 : : }
698 : : }
699 : 12 : if (!mult_stmts.is_empty ())
700 : : {
701 : : /* r2 = a * x. Transform this into:
702 : : r2 = t (The original sqrt (a)). */
703 : : unsigned int i;
704 : 24 : gimple *mult_stmt = NULL;
705 : 24 : FOR_EACH_VEC_ELT (mult_stmts, i, mult_stmt)
706 : : {
707 : 12 : gimple_stmt_iterator gsi2 = gsi_for_stmt (mult_stmt);
708 : :
709 : 12 : if (dump_file)
710 : : {
711 : 10 : fprintf (dump_file, "Replacing squaring multiplication\n");
712 : 10 : print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
713 : 10 : fprintf (dump_file, "with assignment\n");
714 : : }
715 : 12 : gimple_assign_set_rhs_from_tree (&gsi2, orig_sqrt_ssa_name);
716 : 12 : fold_stmt_inplace (&gsi2);
717 : 12 : update_stmt (mult_stmt);
718 : 12 : if (dump_file)
719 : 10 : print_gimple_stmt (dump_file, mult_stmt, 0, TDF_NONE);
720 : : }
721 : : }
722 : :
723 : 12 : if (has_other_use)
724 : : {
725 : : /* Using the two temporaries tmp1, tmp2 from above
726 : : the original x is now:
727 : : x = tmp1 * tmp2. */
728 : 10 : gcc_assert (orig_sqrt_ssa_name);
729 : 10 : gcc_assert (sqr_ssa_name);
730 : :
731 : 10 : gimple *new_stmt
732 : 10 : = gimple_build_assign (x, MULT_EXPR,
733 : : orig_sqrt_ssa_name, sqr_ssa_name);
734 : 10 : gsi_insert_after (def_gsi, new_stmt, GSI_NEW_STMT);
735 : 10 : update_stmt (stmt);
736 : : }
737 : 2 : else if (delete_div)
738 : : {
739 : : /* Remove the original division. */
740 : 2 : gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
741 : 2 : gsi_remove (&gsi2, true);
742 : 2 : release_defs (stmt);
743 : : }
744 : : else
745 : 0 : release_ssa_name (x);
746 : : }
747 : :
748 : : /* Look for floating-point divisions among DEF's uses, and try to
749 : : replace them by multiplications with the reciprocal. Add
750 : : as many statements computing the reciprocal as needed.
751 : :
752 : : DEF must be a GIMPLE register of a floating-point type. */
753 : :
754 : : static void
755 : 217772 : execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
756 : : {
757 : 217772 : use_operand_p use_p, square_use_p;
758 : 217772 : imm_use_iterator use_iter, square_use_iter;
759 : 217772 : tree square_def;
760 : 217772 : struct occurrence *occ;
761 : 217772 : int count = 0;
762 : 217772 : int threshold;
763 : 217772 : int square_recip_count = 0;
764 : 217772 : int sqrt_recip_count = 0;
765 : :
766 : 217772 : gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && TREE_CODE (def) == SSA_NAME);
767 : 217772 : threshold = targetm.min_divisions_for_recip_mul (TYPE_MODE (TREE_TYPE (def)));
768 : :
769 : : /* If DEF is a square (x * x), count the number of divisions by x.
770 : : If there are more divisions by x than by (DEF * DEF), prefer to optimize
771 : : the reciprocal of x instead of DEF. This improves cases like:
772 : : def = x * x
773 : : t0 = a / def
774 : : t1 = b / def
775 : : t2 = c / x
776 : : Reciprocal optimization of x results in 1 division rather than 2 or 3. */
777 : 217772 : gimple *def_stmt = SSA_NAME_DEF_STMT (def);
778 : :
779 : 217772 : if (is_gimple_assign (def_stmt)
780 : 163742 : && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
781 : 39600 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
782 : 257294 : && gimple_assign_rhs1 (def_stmt) == gimple_assign_rhs2 (def_stmt))
783 : : {
784 : 652 : tree op0 = gimple_assign_rhs1 (def_stmt);
785 : :
786 : 2649 : FOR_EACH_IMM_USE_FAST (use_p, use_iter, op0)
787 : : {
788 : 1997 : gimple *use_stmt = USE_STMT (use_p);
789 : 1997 : if (is_division_by (use_stmt, op0))
790 : 14 : sqrt_recip_count++;
791 : : }
792 : : }
793 : :
794 : 573014 : FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
795 : : {
796 : 355242 : gimple *use_stmt = USE_STMT (use_p);
797 : 355242 : if (is_division_by (use_stmt, def))
798 : : {
799 : 610 : register_division_in (gimple_bb (use_stmt), 2);
800 : 610 : count++;
801 : : }
802 : :
803 : 355242 : if (is_square_of (use_stmt, def))
804 : : {
805 : 1312 : square_def = gimple_assign_lhs (use_stmt);
806 : 2768 : FOR_EACH_IMM_USE_FAST (square_use_p, square_use_iter, square_def)
807 : : {
808 : 1456 : gimple *square_use_stmt = USE_STMT (square_use_p);
809 : 1456 : if (is_division_by (square_use_stmt, square_def))
810 : : {
811 : : /* This is executed twice for each division by a square. */
812 : 66 : register_division_in (gimple_bb (square_use_stmt), 1);
813 : 66 : square_recip_count++;
814 : : }
815 : : }
816 : : }
817 : : }
818 : :
819 : : /* Square reciprocals were counted twice above. */
820 : 217772 : square_recip_count /= 2;
821 : :
822 : : /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */
823 : 217772 : if (sqrt_recip_count > square_recip_count)
824 : 14 : goto out;
825 : :
826 : : /* Do the expensive part only if we can hope to optimize something. */
827 : 217758 : if (count + square_recip_count >= threshold && count >= 1)
828 : : {
829 : 26 : gimple *use_stmt;
830 : 52 : for (occ = occ_head; occ; occ = occ->next)
831 : : {
832 : 26 : compute_merit (occ);
833 : 26 : insert_reciprocals (def_gsi, occ, def, NULL, NULL,
834 : : square_recip_count, threshold);
835 : : }
836 : :
837 : 159 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, def)
838 : : {
839 : 133 : if (is_division_by (use_stmt, def))
840 : : {
841 : 345 : FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
842 : 115 : replace_reciprocal (use_p);
843 : : }
844 : 23 : else if (square_recip_count > 0 && is_square_of (use_stmt, def))
845 : : {
846 : 20 : FOR_EACH_IMM_USE_ON_STMT (use_p, use_iter)
847 : : {
848 : : /* Find all uses of the square that are divisions and
849 : : * replace them by multiplications with the inverse. */
850 : 8 : imm_use_iterator square_iterator;
851 : 8 : gimple *powmult_use_stmt = USE_STMT (use_p);
852 : 8 : tree powmult_def_name = gimple_assign_lhs (powmult_use_stmt);
853 : :
854 : 16 : FOR_EACH_IMM_USE_STMT (powmult_use_stmt,
855 : : square_iterator, powmult_def_name)
856 : 24 : FOR_EACH_IMM_USE_ON_STMT (square_use_p, square_iterator)
857 : : {
858 : 8 : gimple *powmult_use_stmt = USE_STMT (square_use_p);
859 : 8 : if (is_division_by (powmult_use_stmt, powmult_def_name))
860 : 4 : replace_reciprocal_squares (square_use_p);
861 : 8 : }
862 : : }
863 : : }
864 : 26 : }
865 : : }
866 : :
867 : 217732 : out:
868 : 218363 : for (occ = occ_head; occ; )
869 : 591 : occ = free_bb (occ);
870 : :
871 : 217772 : occ_head = NULL;
872 : 217772 : }
873 : :
874 : : /* Return an internal function that implements the reciprocal of CALL,
875 : : or IFN_LAST if there is no such function that the target supports. */
876 : :
877 : : internal_fn
878 : 131 : internal_fn_reciprocal (gcall *call)
879 : : {
880 : 131 : internal_fn ifn;
881 : :
882 : 131 : switch (gimple_call_combined_fn (call))
883 : : {
884 : 115 : CASE_CFN_SQRT:
885 : 115 : CASE_CFN_SQRT_FN:
886 : 115 : ifn = IFN_RSQRT;
887 : 115 : break;
888 : :
889 : : default:
890 : : return IFN_LAST;
891 : : }
892 : :
893 : 115 : tree_pair types = direct_internal_fn_types (ifn, call);
894 : 115 : if (!direct_internal_fn_supported_p (ifn, types, OPTIMIZE_FOR_SPEED))
895 : : return IFN_LAST;
896 : :
897 : : return ifn;
898 : : }
899 : :
900 : : /* Go through all the floating-point SSA_NAMEs, and call
901 : : execute_cse_reciprocals_1 on each of them. */
902 : : namespace {
903 : :
904 : : const pass_data pass_data_cse_reciprocals =
905 : : {
906 : : GIMPLE_PASS, /* type */
907 : : "recip", /* name */
908 : : OPTGROUP_NONE, /* optinfo_flags */
909 : : TV_TREE_RECIP, /* tv_id */
910 : : PROP_ssa, /* properties_required */
911 : : 0, /* properties_provided */
912 : : 0, /* properties_destroyed */
913 : : 0, /* todo_flags_start */
914 : : TODO_update_ssa, /* todo_flags_finish */
915 : : };
916 : :
917 : : class pass_cse_reciprocals : public gimple_opt_pass
918 : : {
919 : : public:
920 : 289080 : pass_cse_reciprocals (gcc::context *ctxt)
921 : 578160 : : gimple_opt_pass (pass_data_cse_reciprocals, ctxt)
922 : : {}
923 : :
924 : : /* opt_pass methods: */
925 : 1035897 : bool gate (function *) final override
926 : : {
927 : 1035897 : return optimize && flag_reciprocal_math;
928 : : }
929 : : unsigned int execute (function *) final override;
930 : :
931 : : }; // class pass_cse_reciprocals
932 : :
933 : : unsigned int
934 : 8710 : pass_cse_reciprocals::execute (function *fun)
935 : : {
936 : 8710 : basic_block bb;
937 : 8710 : tree arg;
938 : :
939 : 8710 : occ_pool = new object_allocator<occurrence> ("dominators for recip");
940 : :
941 : 8710 : memset (&reciprocal_stats, 0, sizeof (reciprocal_stats));
942 : 8710 : calculate_dominance_info (CDI_DOMINATORS);
943 : 8710 : calculate_dominance_info (CDI_POST_DOMINATORS);
944 : :
945 : 8710 : if (flag_checking)
946 : 97380 : FOR_EACH_BB_FN (bb, fun)
947 : 88670 : gcc_assert (!bb->aux);
948 : :
949 : 21500 : for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg))
950 : 20246 : if (FLOAT_TYPE_P (TREE_TYPE (arg))
951 : 13875 : && is_gimple_reg (arg))
952 : : {
953 : 6419 : tree name = ssa_default_def (fun, arg);
954 : 6419 : if (name)
955 : 5424 : execute_cse_reciprocals_1 (NULL, name);
956 : : }
957 : :
958 : 97380 : FOR_EACH_BB_FN (bb, fun)
959 : : {
960 : 88670 : tree def;
961 : :
962 : 210333 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
963 : 121663 : gsi_next (&gsi))
964 : : {
965 : 121663 : gphi *phi = gsi.phi ();
966 : 121663 : def = PHI_RESULT (phi);
967 : 121663 : if (! virtual_operand_p (def)
968 : 121663 : && FLOAT_TYPE_P (TREE_TYPE (def)))
969 : 38550 : execute_cse_reciprocals_1 (NULL, def);
970 : : }
971 : :
972 : 1367432 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
973 : 1278762 : gsi_next (&gsi))
974 : : {
975 : 1278762 : gimple *stmt = gsi_stmt (gsi);
976 : :
977 : 2557524 : if (gimple_has_lhs (stmt)
978 : 798199 : && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
979 : 757424 : && FLOAT_TYPE_P (TREE_TYPE (def))
980 : 196535 : && TREE_CODE (def) == SSA_NAME)
981 : : {
982 : 173798 : execute_cse_reciprocals_1 (&gsi, def);
983 : 173798 : stmt = gsi_stmt (gsi);
984 : 173798 : if (flag_unsafe_math_optimizations
985 : 173769 : && is_gimple_assign (stmt)
986 : 163715 : && gimple_assign_lhs (stmt) == def
987 : 163713 : && !stmt_can_throw_internal (cfun, stmt)
988 : 337467 : && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
989 : 538 : optimize_recip_sqrt (&gsi, def);
990 : : }
991 : : }
992 : :
993 : 88670 : if (optimize_bb_for_size_p (bb))
994 : 5358 : continue;
995 : :
996 : : /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b). */
997 : 1352102 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
998 : 1268790 : gsi_next (&gsi))
999 : : {
1000 : 1268790 : gimple *stmt = gsi_stmt (gsi);
1001 : :
1002 : 1268790 : if (is_gimple_assign (stmt)
1003 : 1268790 : && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
1004 : : {
1005 : 573 : tree arg1 = gimple_assign_rhs2 (stmt);
1006 : 573 : gimple *stmt1;
1007 : :
1008 : 573 : if (TREE_CODE (arg1) != SSA_NAME)
1009 : 5 : continue;
1010 : :
1011 : 568 : stmt1 = SSA_NAME_DEF_STMT (arg1);
1012 : :
1013 : 568 : if (is_gimple_call (stmt1)
1014 : 568 : && gimple_call_lhs (stmt1))
1015 : : {
1016 : 131 : bool fail;
1017 : 131 : imm_use_iterator ui;
1018 : 131 : use_operand_p use_p;
1019 : 131 : tree fndecl = NULL_TREE;
1020 : :
1021 : 131 : gcall *call = as_a <gcall *> (stmt1);
1022 : 131 : internal_fn ifn = internal_fn_reciprocal (call);
1023 : 131 : if (ifn == IFN_LAST)
1024 : : {
1025 : 66 : fndecl = gimple_call_fndecl (call);
1026 : 132 : if (!fndecl
1027 : 66 : || !fndecl_built_in_p (fndecl, BUILT_IN_MD))
1028 : 68 : continue;
1029 : 0 : fndecl = targetm.builtin_reciprocal (fndecl);
1030 : 0 : if (!fndecl)
1031 : 0 : continue;
1032 : : }
1033 : :
1034 : : /* Check that all uses of the SSA name are divisions,
1035 : : otherwise replacing the defining statement will do
1036 : : the wrong thing. */
1037 : 65 : fail = false;
1038 : 130 : FOR_EACH_IMM_USE_FAST (use_p, ui, arg1)
1039 : : {
1040 : 67 : gimple *stmt2 = USE_STMT (use_p);
1041 : 67 : if (is_gimple_debug (stmt2))
1042 : 0 : continue;
1043 : 67 : if (!is_gimple_assign (stmt2)
1044 : 67 : || gimple_assign_rhs_code (stmt2) != RDIV_EXPR
1045 : 65 : || gimple_assign_rhs1 (stmt2) == arg1
1046 : 132 : || gimple_assign_rhs2 (stmt2) != arg1)
1047 : : {
1048 : : fail = true;
1049 : : break;
1050 : : }
1051 : : }
1052 : 65 : if (fail)
1053 : 2 : continue;
1054 : :
1055 : 63 : gimple_replace_ssa_lhs (call, arg1);
1056 : 63 : reset_flow_sensitive_info (arg1);
1057 : 63 : if (gimple_call_internal_p (call) != (ifn != IFN_LAST))
1058 : : {
1059 : 46 : auto_vec<tree, 4> args;
1060 : 46 : for (unsigned int i = 0;
1061 : 92 : i < gimple_call_num_args (call); i++)
1062 : 46 : args.safe_push (gimple_call_arg (call, i));
1063 : 46 : gcall *stmt2;
1064 : 46 : if (ifn == IFN_LAST)
1065 : 0 : stmt2 = gimple_build_call_vec (fndecl, args);
1066 : : else
1067 : 46 : stmt2 = gimple_build_call_internal_vec (ifn, args);
1068 : 46 : gimple_call_set_lhs (stmt2, arg1);
1069 : 46 : gimple_move_vops (stmt2, call);
1070 : 46 : gimple_call_set_nothrow (stmt2,
1071 : 46 : gimple_call_nothrow_p (call));
1072 : 46 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
1073 : 46 : gsi_replace (&gsi2, stmt2, true);
1074 : 46 : }
1075 : : else
1076 : : {
1077 : 17 : if (ifn == IFN_LAST)
1078 : 0 : gimple_call_set_fndecl (call, fndecl);
1079 : : else
1080 : 17 : gimple_call_set_internal_fn (call, ifn);
1081 : 17 : update_stmt (call);
1082 : : }
1083 : 63 : reciprocal_stats.rfuncs_inserted++;
1084 : :
1085 : 126 : FOR_EACH_IMM_USE_STMT (stmt, ui, arg1)
1086 : : {
1087 : 63 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
1088 : 63 : gimple_assign_set_rhs_code (stmt, MULT_EXPR);
1089 : 63 : fold_stmt_inplace (&gsi);
1090 : 63 : update_stmt (stmt);
1091 : 63 : }
1092 : : }
1093 : : }
1094 : : }
1095 : : }
1096 : :
1097 : 8710 : statistics_counter_event (fun, "reciprocal divs inserted",
1098 : : reciprocal_stats.rdivs_inserted);
1099 : 8710 : statistics_counter_event (fun, "reciprocal functions inserted",
1100 : : reciprocal_stats.rfuncs_inserted);
1101 : :
1102 : 8710 : free_dominance_info (CDI_DOMINATORS);
1103 : 8710 : free_dominance_info (CDI_POST_DOMINATORS);
1104 : 17420 : delete occ_pool;
1105 : 8710 : return 0;
1106 : : }
1107 : :
1108 : : } // anon namespace
1109 : :
1110 : : gimple_opt_pass *
1111 : 289080 : make_pass_cse_reciprocals (gcc::context *ctxt)
1112 : : {
1113 : 289080 : return new pass_cse_reciprocals (ctxt);
1114 : : }
1115 : :
1116 : : /* If NAME is the result of a type conversion, look for other
1117 : : equivalent dominating or dominated conversions, and replace all
1118 : : uses with the earliest dominating name, removing the redundant
1119 : : conversions. Return the prevailing name. */
1120 : :
1121 : : static tree
1122 : 1030 : execute_cse_conv_1 (tree name, bool *cfg_changed)
1123 : : {
1124 : 1030 : if (SSA_NAME_IS_DEFAULT_DEF (name)
1125 : 1030 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
1126 : : return name;
1127 : :
1128 : 938 : gimple *def_stmt = SSA_NAME_DEF_STMT (name);
1129 : :
1130 : 938 : if (!gimple_assign_cast_p (def_stmt))
1131 : : return name;
1132 : :
1133 : 136 : tree src = gimple_assign_rhs1 (def_stmt);
1134 : :
1135 : 136 : if (TREE_CODE (src) != SSA_NAME)
1136 : : return name;
1137 : :
1138 : 136 : imm_use_iterator use_iter;
1139 : 136 : gimple *use_stmt;
1140 : :
1141 : : /* Find the earliest dominating def. */
1142 : 521 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, src)
1143 : : {
1144 : 763 : if (use_stmt == def_stmt
1145 : 385 : || !gimple_assign_cast_p (use_stmt))
1146 : 763 : continue;
1147 : :
1148 : 7 : tree lhs = gimple_assign_lhs (use_stmt);
1149 : :
1150 : 7 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
1151 : 14 : || (gimple_assign_rhs1 (use_stmt)
1152 : 7 : != gimple_assign_rhs1 (def_stmt))
1153 : 14 : || !types_compatible_p (TREE_TYPE (name), TREE_TYPE (lhs)))
1154 : 0 : continue;
1155 : :
1156 : 7 : bool use_dominates;
1157 : 7 : if (gimple_bb (def_stmt) == gimple_bb (use_stmt))
1158 : : {
1159 : 0 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1160 : 0 : while (!gsi_end_p (gsi) && gsi_stmt (gsi) != def_stmt)
1161 : 0 : gsi_next (&gsi);
1162 : 0 : use_dominates = !gsi_end_p (gsi);
1163 : : }
1164 : 7 : else if (dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt),
1165 : 7 : gimple_bb (def_stmt)))
1166 : : use_dominates = false;
1167 : 7 : else if (dominated_by_p (CDI_DOMINATORS, gimple_bb (def_stmt),
1168 : 7 : gimple_bb (use_stmt)))
1169 : : use_dominates = true;
1170 : : else
1171 : 4 : continue;
1172 : :
1173 : 0 : if (use_dominates)
1174 : : {
1175 : : std::swap (name, lhs);
1176 : : std::swap (def_stmt, use_stmt);
1177 : : }
1178 : 136 : }
1179 : :
1180 : : /* Now go through all uses of SRC again, replacing the equivalent
1181 : : dominated conversions. We may replace defs that were not
1182 : : dominated by the then-prevailing defs when we first visited
1183 : : them. */
1184 : 521 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, src)
1185 : : {
1186 : 763 : if (use_stmt == def_stmt
1187 : 385 : || !gimple_assign_cast_p (use_stmt))
1188 : 378 : continue;
1189 : :
1190 : 7 : tree lhs = gimple_assign_lhs (use_stmt);
1191 : :
1192 : 7 : if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
1193 : 14 : || (gimple_assign_rhs1 (use_stmt)
1194 : 7 : != gimple_assign_rhs1 (def_stmt))
1195 : 14 : || !types_compatible_p (TREE_TYPE (name), TREE_TYPE (lhs)))
1196 : 0 : continue;
1197 : :
1198 : 7 : basic_block use_bb = gimple_bb (use_stmt);
1199 : 7 : if (gimple_bb (def_stmt) == use_bb
1200 : 7 : || dominated_by_p (CDI_DOMINATORS, use_bb, gimple_bb (def_stmt)))
1201 : : {
1202 : 3 : sincos_stats.conv_removed++;
1203 : :
1204 : 3 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
1205 : 3 : replace_uses_by (lhs, name);
1206 : 3 : if (gsi_remove (&gsi, true)
1207 : 3 : && gimple_purge_dead_eh_edges (use_bb))
1208 : 3 : *cfg_changed = true;
1209 : 3 : release_defs (use_stmt);
1210 : : }
1211 : 136 : }
1212 : :
1213 : 136 : return name;
1214 : : }
1215 : :
1216 : : /* Records an occurrence at statement USE_STMT in the vector of trees
1217 : : STMTS if it is dominated by *TOP_BB or dominates it or this basic block
1218 : : is not yet initialized. Returns true if the occurrence was pushed on
1219 : : the vector. Adjusts *TOP_BB to be the basic block dominating all
1220 : : statements in the vector. */
1221 : :
1222 : : static bool
1223 : 1239 : maybe_record_sincos (vec<gimple *> *stmts,
1224 : : basic_block *top_bb, gimple *use_stmt)
1225 : : {
1226 : 1239 : basic_block use_bb = gimple_bb (use_stmt);
1227 : 1239 : if (*top_bb
1228 : 1239 : && (*top_bb == use_bb
1229 : 66 : || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
1230 : 150 : stmts->safe_push (use_stmt);
1231 : 1089 : else if (!*top_bb
1232 : 1089 : || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
1233 : : {
1234 : 1069 : stmts->safe_push (use_stmt);
1235 : 1069 : *top_bb = use_bb;
1236 : : }
1237 : : else
1238 : : return false;
1239 : :
1240 : : return true;
1241 : : }
1242 : :
1243 : : /* Look for sin, cos and cexpi calls with the same argument NAME and
1244 : : create a single call to cexpi CSEing the result in this case.
1245 : : We first walk over all immediate uses of the argument collecting
1246 : : statements that we can CSE in a vector and in a second pass replace
1247 : : the statement rhs with a REALPART or IMAGPART expression on the
1248 : : result of the cexpi call we insert before the use statement that
1249 : : dominates all other candidates. */
1250 : :
1251 : : static bool
1252 : 1030 : execute_cse_sincos_1 (tree name)
1253 : : {
1254 : 1030 : gimple_stmt_iterator gsi;
1255 : 1030 : imm_use_iterator use_iter;
1256 : 1030 : tree fndecl, res, type = NULL_TREE;
1257 : 1030 : gimple *def_stmt, *use_stmt, *stmt;
1258 : 1030 : int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
1259 : 1030 : auto_vec<gimple *> stmts;
1260 : 1030 : basic_block top_bb = NULL;
1261 : 1030 : int i;
1262 : 1030 : bool cfg_changed = false;
1263 : :
1264 : 1030 : name = execute_cse_conv_1 (name, &cfg_changed);
1265 : :
1266 : 3966 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
1267 : : {
1268 : 2936 : if (gimple_code (use_stmt) != GIMPLE_CALL
1269 : 2936 : || !gimple_call_lhs (use_stmt))
1270 : 1668 : continue;
1271 : :
1272 : 1268 : switch (gimple_call_combined_fn (use_stmt))
1273 : : {
1274 : 452 : CASE_CFN_COS:
1275 : 452 : seen_cos |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
1276 : 452 : break;
1277 : :
1278 : 781 : CASE_CFN_SIN:
1279 : 781 : seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
1280 : 781 : break;
1281 : :
1282 : 6 : CASE_CFN_CEXPI:
1283 : 6 : seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
1284 : 6 : break;
1285 : :
1286 : 29 : default:;
1287 : 29 : continue;
1288 : : }
1289 : :
1290 : 1239 : tree t = mathfn_built_in_type (gimple_call_combined_fn (use_stmt));
1291 : 1239 : if (!type)
1292 : : {
1293 : 1030 : type = t;
1294 : 1030 : t = TREE_TYPE (name);
1295 : : }
1296 : : /* This checks that NAME has the right type in the first round,
1297 : : and, in subsequent rounds, that the built_in type is the same
1298 : : type, or a compatible type. */
1299 : 1239 : if (type != t && !types_compatible_p (type, t))
1300 : 0 : return false;
1301 : 1030 : }
1302 : 1030 : if (seen_cos + seen_sin + seen_cexpi <= 1)
1303 : : return false;
1304 : :
1305 : : /* Simply insert cexpi at the beginning of top_bb but not earlier than
1306 : : the name def statement. */
1307 : 189 : fndecl = mathfn_built_in (type, BUILT_IN_CEXPI);
1308 : 189 : if (!fndecl)
1309 : : return false;
1310 : 145 : stmt = gimple_build_call (fndecl, 1, name);
1311 : 145 : res = make_temp_ssa_name (TREE_TYPE (TREE_TYPE (fndecl)), stmt, "sincostmp");
1312 : 145 : gimple_call_set_lhs (stmt, res);
1313 : :
1314 : 145 : def_stmt = SSA_NAME_DEF_STMT (name);
1315 : 145 : if (!SSA_NAME_IS_DEFAULT_DEF (name)
1316 : 120 : && gimple_code (def_stmt) != GIMPLE_PHI
1317 : 257 : && gimple_bb (def_stmt) == top_bb)
1318 : : {
1319 : 112 : gsi = gsi_for_stmt (def_stmt);
1320 : 112 : gsi_insert_after (&gsi, stmt, GSI_SAME_STMT);
1321 : : }
1322 : : else
1323 : : {
1324 : 33 : gsi = gsi_after_labels (top_bb);
1325 : 33 : gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
1326 : : }
1327 : 145 : sincos_stats.inserted++;
1328 : :
1329 : : /* And adjust the recorded old call sites. */
1330 : 435 : for (i = 0; stmts.iterate (i, &use_stmt); ++i)
1331 : : {
1332 : 290 : tree rhs = NULL;
1333 : :
1334 : 290 : switch (gimple_call_combined_fn (use_stmt))
1335 : : {
1336 : 145 : CASE_CFN_COS:
1337 : 145 : rhs = fold_build1 (REALPART_EXPR, type, res);
1338 : 145 : break;
1339 : :
1340 : 145 : CASE_CFN_SIN:
1341 : 145 : rhs = fold_build1 (IMAGPART_EXPR, type, res);
1342 : 145 : break;
1343 : :
1344 : : CASE_CFN_CEXPI:
1345 : : rhs = res;
1346 : : break;
1347 : :
1348 : 0 : default:;
1349 : 0 : gcc_unreachable ();
1350 : : }
1351 : :
1352 : : /* Replace call with a copy. */
1353 : 290 : stmt = gimple_build_assign (gimple_call_lhs (use_stmt), rhs);
1354 : :
1355 : 290 : gsi = gsi_for_stmt (use_stmt);
1356 : 290 : gsi_replace (&gsi, stmt, true);
1357 : 290 : if (gimple_purge_dead_eh_edges (gimple_bb (stmt)))
1358 : 0 : cfg_changed = true;
1359 : : }
1360 : :
1361 : 145 : return cfg_changed;
1362 : 1030 : }
1363 : :
1364 : : /* To evaluate powi(x,n), the floating point value x raised to the
1365 : : constant integer exponent n, we use a hybrid algorithm that
1366 : : combines the "window method" with look-up tables. For an
1367 : : introduction to exponentiation algorithms and "addition chains",
1368 : : see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
1369 : : "Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
1370 : : 3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
1371 : : Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998. */
1372 : :
1373 : : /* Provide a default value for POWI_MAX_MULTS, the maximum number of
1374 : : multiplications to inline before calling the system library's pow
1375 : : function. powi(x,n) requires at worst 2*bits(n)-2 multiplications,
1376 : : so this default never requires calling pow, powf or powl. */
1377 : :
1378 : : #ifndef POWI_MAX_MULTS
1379 : : #define POWI_MAX_MULTS (2*HOST_BITS_PER_WIDE_INT-2)
1380 : : #endif
1381 : :
1382 : : /* The size of the "optimal power tree" lookup table. All
1383 : : exponents less than this value are simply looked up in the
1384 : : powi_table below. This threshold is also used to size the
1385 : : cache of pseudo registers that hold intermediate results. */
1386 : : #define POWI_TABLE_SIZE 256
1387 : :
1388 : : /* The size, in bits of the window, used in the "window method"
1389 : : exponentiation algorithm. This is equivalent to a radix of
1390 : : (1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method". */
1391 : : #define POWI_WINDOW_SIZE 3
1392 : :
1393 : : /* The following table is an efficient representation of an
1394 : : "optimal power tree". For each value, i, the corresponding
1395 : : value, j, in the table states than an optimal evaluation
1396 : : sequence for calculating pow(x,i) can be found by evaluating
1397 : : pow(x,j)*pow(x,i-j). An optimal power tree for the first
1398 : : 100 integers is given in Knuth's "Seminumerical algorithms". */
1399 : :
1400 : : static const unsigned char powi_table[POWI_TABLE_SIZE] =
1401 : : {
1402 : : 0, 1, 1, 2, 2, 3, 3, 4, /* 0 - 7 */
1403 : : 4, 6, 5, 6, 6, 10, 7, 9, /* 8 - 15 */
1404 : : 8, 16, 9, 16, 10, 12, 11, 13, /* 16 - 23 */
1405 : : 12, 17, 13, 18, 14, 24, 15, 26, /* 24 - 31 */
1406 : : 16, 17, 17, 19, 18, 33, 19, 26, /* 32 - 39 */
1407 : : 20, 25, 21, 40, 22, 27, 23, 44, /* 40 - 47 */
1408 : : 24, 32, 25, 34, 26, 29, 27, 44, /* 48 - 55 */
1409 : : 28, 31, 29, 34, 30, 60, 31, 36, /* 56 - 63 */
1410 : : 32, 64, 33, 34, 34, 46, 35, 37, /* 64 - 71 */
1411 : : 36, 65, 37, 50, 38, 48, 39, 69, /* 72 - 79 */
1412 : : 40, 49, 41, 43, 42, 51, 43, 58, /* 80 - 87 */
1413 : : 44, 64, 45, 47, 46, 59, 47, 76, /* 88 - 95 */
1414 : : 48, 65, 49, 66, 50, 67, 51, 66, /* 96 - 103 */
1415 : : 52, 70, 53, 74, 54, 104, 55, 74, /* 104 - 111 */
1416 : : 56, 64, 57, 69, 58, 78, 59, 68, /* 112 - 119 */
1417 : : 60, 61, 61, 80, 62, 75, 63, 68, /* 120 - 127 */
1418 : : 64, 65, 65, 128, 66, 129, 67, 90, /* 128 - 135 */
1419 : : 68, 73, 69, 131, 70, 94, 71, 88, /* 136 - 143 */
1420 : : 72, 128, 73, 98, 74, 132, 75, 121, /* 144 - 151 */
1421 : : 76, 102, 77, 124, 78, 132, 79, 106, /* 152 - 159 */
1422 : : 80, 97, 81, 160, 82, 99, 83, 134, /* 160 - 167 */
1423 : : 84, 86, 85, 95, 86, 160, 87, 100, /* 168 - 175 */
1424 : : 88, 113, 89, 98, 90, 107, 91, 122, /* 176 - 183 */
1425 : : 92, 111, 93, 102, 94, 126, 95, 150, /* 184 - 191 */
1426 : : 96, 128, 97, 130, 98, 133, 99, 195, /* 192 - 199 */
1427 : : 100, 128, 101, 123, 102, 164, 103, 138, /* 200 - 207 */
1428 : : 104, 145, 105, 146, 106, 109, 107, 149, /* 208 - 215 */
1429 : : 108, 200, 109, 146, 110, 170, 111, 157, /* 216 - 223 */
1430 : : 112, 128, 113, 130, 114, 182, 115, 132, /* 224 - 231 */
1431 : : 116, 200, 117, 132, 118, 158, 119, 206, /* 232 - 239 */
1432 : : 120, 240, 121, 162, 122, 147, 123, 152, /* 240 - 247 */
1433 : : 124, 166, 125, 214, 126, 138, 127, 153, /* 248 - 255 */
1434 : : };
1435 : :
1436 : :
1437 : : /* Return the number of multiplications required to calculate
1438 : : powi(x,n) where n is less than POWI_TABLE_SIZE. This is a
1439 : : subroutine of powi_cost. CACHE is an array indicating
1440 : : which exponents have already been calculated. */
1441 : :
1442 : : static int
1443 : 1122 : powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
1444 : : {
1445 : : /* If we've already calculated this exponent, then this evaluation
1446 : : doesn't require any additional multiplications. */
1447 : 1864 : if (cache[n])
1448 : 1122 : return 0;
1449 : :
1450 : 742 : cache[n] = true;
1451 : 742 : return powi_lookup_cost (n - powi_table[n], cache)
1452 : 742 : + powi_lookup_cost (powi_table[n], cache) + 1;
1453 : : }
1454 : :
1455 : : /* Return the number of multiplications required to calculate
1456 : : powi(x,n) for an arbitrary x, given the exponent N. This
1457 : : function needs to be kept in sync with powi_as_mults below. */
1458 : :
1459 : : static int
1460 : 385 : powi_cost (HOST_WIDE_INT n)
1461 : : {
1462 : 385 : bool cache[POWI_TABLE_SIZE];
1463 : 385 : unsigned HOST_WIDE_INT digit;
1464 : 385 : unsigned HOST_WIDE_INT val;
1465 : 385 : int result;
1466 : :
1467 : 385 : if (n == 0)
1468 : : return 0;
1469 : :
1470 : : /* Ignore the reciprocal when calculating the cost. */
1471 : 380 : val = absu_hwi (n);
1472 : :
1473 : : /* Initialize the exponent cache. */
1474 : 380 : memset (cache, 0, POWI_TABLE_SIZE * sizeof (bool));
1475 : 380 : cache[1] = true;
1476 : :
1477 : 380 : result = 0;
1478 : :
1479 : 380 : while (val >= POWI_TABLE_SIZE)
1480 : : {
1481 : 0 : if (val & 1)
1482 : : {
1483 : 0 : digit = val & ((1 << POWI_WINDOW_SIZE) - 1);
1484 : 0 : result += powi_lookup_cost (digit, cache)
1485 : 0 : + POWI_WINDOW_SIZE + 1;
1486 : 0 : val >>= POWI_WINDOW_SIZE;
1487 : : }
1488 : : else
1489 : : {
1490 : 0 : val >>= 1;
1491 : 0 : result++;
1492 : : }
1493 : : }
1494 : :
1495 : 380 : return result + powi_lookup_cost (val, cache);
1496 : : }
1497 : :
1498 : : /* Recursive subroutine of powi_as_mults. This function takes the
1499 : : array, CACHE, of already calculated exponents and an exponent N and
1500 : : returns a tree that corresponds to CACHE[1]**N, with type TYPE. */
1501 : :
1502 : : static tree
1503 : 6005 : powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type,
1504 : : unsigned HOST_WIDE_INT n, tree *cache)
1505 : : {
1506 : 6005 : tree op0, op1, ssa_target;
1507 : 6005 : unsigned HOST_WIDE_INT digit;
1508 : 6005 : gassign *mult_stmt;
1509 : :
1510 : 6005 : if (n < POWI_TABLE_SIZE && cache[n])
1511 : : return cache[n];
1512 : :
1513 : 2130 : ssa_target = make_temp_ssa_name (type, NULL, "powmult");
1514 : :
1515 : 2130 : if (n < POWI_TABLE_SIZE)
1516 : : {
1517 : 2127 : cache[n] = ssa_target;
1518 : 2127 : op0 = powi_as_mults_1 (gsi, loc, type, n - powi_table[n], cache);
1519 : 2127 : op1 = powi_as_mults_1 (gsi, loc, type, powi_table[n], cache);
1520 : : }
1521 : 3 : else if (n & 1)
1522 : : {
1523 : 1 : digit = n & ((1 << POWI_WINDOW_SIZE) - 1);
1524 : 1 : op0 = powi_as_mults_1 (gsi, loc, type, n - digit, cache);
1525 : 1 : op1 = powi_as_mults_1 (gsi, loc, type, digit, cache);
1526 : : }
1527 : : else
1528 : : {
1529 : 2 : op0 = powi_as_mults_1 (gsi, loc, type, n >> 1, cache);
1530 : 2 : op1 = op0;
1531 : : }
1532 : :
1533 : 2130 : mult_stmt = gimple_build_assign (ssa_target, MULT_EXPR, op0, op1);
1534 : 2130 : gimple_set_location (mult_stmt, loc);
1535 : 2130 : gsi_insert_before (gsi, mult_stmt, GSI_SAME_STMT);
1536 : :
1537 : 2130 : return ssa_target;
1538 : : }
1539 : :
1540 : : /* Convert ARG0**N to a tree of multiplications of ARG0 with itself.
1541 : : This function needs to be kept in sync with powi_cost above. */
1542 : :
1543 : : tree
1544 : 1747 : powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
1545 : : tree arg0, HOST_WIDE_INT n)
1546 : : {
1547 : 1747 : tree cache[POWI_TABLE_SIZE], result, type = TREE_TYPE (arg0);
1548 : 1747 : gassign *div_stmt;
1549 : 1747 : tree target;
1550 : :
1551 : 1747 : if (n == 0)
1552 : 0 : return build_one_cst (type);
1553 : :
1554 : 1747 : memset (cache, 0, sizeof (cache));
1555 : 1747 : cache[1] = arg0;
1556 : :
1557 : 1747 : result = powi_as_mults_1 (gsi, loc, type, absu_hwi (n), cache);
1558 : 1747 : if (n >= 0)
1559 : : return result;
1560 : :
1561 : : /* If the original exponent was negative, reciprocate the result. */
1562 : 8 : target = make_temp_ssa_name (type, NULL, "powmult");
1563 : 8 : div_stmt = gimple_build_assign (target, RDIV_EXPR,
1564 : : build_real (type, dconst1), result);
1565 : 8 : gimple_set_location (div_stmt, loc);
1566 : 8 : gsi_insert_before (gsi, div_stmt, GSI_SAME_STMT);
1567 : :
1568 : 8 : return target;
1569 : : }
1570 : :
1571 : : /* ARG0 and N are the two arguments to a powi builtin in GSI with
1572 : : location info LOC. If the arguments are appropriate, create an
1573 : : equivalent sequence of statements prior to GSI using an optimal
1574 : : number of multiplications, and return an expession holding the
1575 : : result. */
1576 : :
1577 : : static tree
1578 : 646 : gimple_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc,
1579 : : tree arg0, HOST_WIDE_INT n)
1580 : : {
1581 : 646 : if ((n >= -1 && n <= 2)
1582 : 646 : || (optimize_function_for_speed_p (cfun)
1583 : 351 : && powi_cost (n) <= POWI_MAX_MULTS))
1584 : 638 : return powi_as_mults (gsi, loc, arg0, n);
1585 : :
1586 : : return NULL_TREE;
1587 : : }
1588 : :
1589 : : /* Build a gimple call statement that calls FN with argument ARG.
1590 : : Set the lhs of the call statement to a fresh SSA name. Insert the
1591 : : statement prior to GSI's current position, and return the fresh
1592 : : SSA name. */
1593 : :
1594 : : static tree
1595 : 45 : build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc,
1596 : : tree fn, tree arg)
1597 : : {
1598 : 45 : gcall *call_stmt;
1599 : 45 : tree ssa_target;
1600 : :
1601 : 45 : call_stmt = gimple_build_call (fn, 1, arg);
1602 : 45 : ssa_target = make_temp_ssa_name (TREE_TYPE (arg), NULL, "powroot");
1603 : 45 : gimple_set_lhs (call_stmt, ssa_target);
1604 : 45 : gimple_set_location (call_stmt, loc);
1605 : 45 : gsi_insert_before (gsi, call_stmt, GSI_SAME_STMT);
1606 : :
1607 : 45 : return ssa_target;
1608 : : }
1609 : :
1610 : : /* Build a gimple binary operation with the given CODE and arguments
1611 : : ARG0, ARG1, assigning the result to a new SSA name for variable
1612 : : TARGET. Insert the statement prior to GSI's current position, and
1613 : : return the fresh SSA name.*/
1614 : :
1615 : : static tree
1616 : 906 : build_and_insert_binop (gimple_stmt_iterator *gsi, location_t loc,
1617 : : const char *name, enum tree_code code,
1618 : : tree arg0, tree arg1)
1619 : : {
1620 : 906 : tree result = make_temp_ssa_name (TREE_TYPE (arg0), NULL, name);
1621 : 906 : gassign *stmt = gimple_build_assign (result, code, arg0, arg1);
1622 : 906 : gimple_set_location (stmt, loc);
1623 : 906 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1624 : 906 : return result;
1625 : : }
1626 : :
1627 : : /* Build a gimple assignment to cast VAL to TYPE. Insert the statement
1628 : : prior to GSI's current position, and return the fresh SSA name. */
1629 : :
1630 : : static tree
1631 : 17087 : build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
1632 : : tree type, tree val)
1633 : : {
1634 : 0 : return gimple_convert (gsi, true, GSI_SAME_STMT, loc, type, val);
1635 : : }
1636 : :
1637 : : struct pow_synth_sqrt_info
1638 : : {
1639 : : bool *factors;
1640 : : unsigned int deepest;
1641 : : unsigned int num_mults;
1642 : : };
1643 : :
1644 : : /* Return true iff the real value C can be represented as a
1645 : : sum of powers of 0.5 up to N. That is:
1646 : : C == SUM<i from 1..N> (a[i]*(0.5**i)) where a[i] is either 0 or 1.
1647 : : Record in INFO the various parameters of the synthesis algorithm such
1648 : : as the factors a[i], the maximum 0.5 power and the number of
1649 : : multiplications that will be required. */
1650 : :
1651 : : bool
1652 : 34 : representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
1653 : : struct pow_synth_sqrt_info *info)
1654 : : {
1655 : 34 : REAL_VALUE_TYPE factor = dconsthalf;
1656 : 34 : REAL_VALUE_TYPE remainder = c;
1657 : :
1658 : 34 : info->deepest = 0;
1659 : 34 : info->num_mults = 0;
1660 : 34 : memset (info->factors, 0, n * sizeof (bool));
1661 : :
1662 : 98 : for (unsigned i = 0; i < n; i++)
1663 : : {
1664 : 91 : REAL_VALUE_TYPE res;
1665 : :
1666 : : /* If something inexact happened bail out now. */
1667 : 91 : if (real_arithmetic (&res, MINUS_EXPR, &remainder, &factor))
1668 : 27 : return false;
1669 : :
1670 : : /* We have hit zero. The number is representable as a sum
1671 : : of powers of 0.5. */
1672 : 91 : if (real_equal (&res, &dconst0))
1673 : : {
1674 : 27 : info->factors[i] = true;
1675 : 27 : info->deepest = i + 1;
1676 : 27 : return true;
1677 : : }
1678 : 64 : else if (!REAL_VALUE_NEGATIVE (res))
1679 : : {
1680 : 29 : remainder = res;
1681 : 29 : info->factors[i] = true;
1682 : 29 : info->num_mults++;
1683 : : }
1684 : : else
1685 : 35 : info->factors[i] = false;
1686 : :
1687 : 64 : real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
1688 : : }
1689 : : return false;
1690 : : }
1691 : :
1692 : : /* Return the tree corresponding to FN being applied
1693 : : to ARG N times at GSI and LOC.
1694 : : Look up previous results from CACHE if need be.
1695 : : cache[0] should contain just plain ARG i.e. FN applied to ARG 0 times. */
1696 : :
1697 : : static tree
1698 : 65 : get_fn_chain (tree arg, unsigned int n, gimple_stmt_iterator *gsi,
1699 : : tree fn, location_t loc, tree *cache)
1700 : : {
1701 : 65 : tree res = cache[n];
1702 : 65 : if (!res)
1703 : : {
1704 : 41 : tree prev = get_fn_chain (arg, n - 1, gsi, fn, loc, cache);
1705 : 41 : res = build_and_insert_call (gsi, loc, fn, prev);
1706 : 41 : cache[n] = res;
1707 : : }
1708 : :
1709 : 65 : return res;
1710 : : }
1711 : :
1712 : : /* Print to STREAM the repeated application of function FNAME to ARG
1713 : : N times. So, for FNAME = "foo", ARG = "x", N = 2 it would print:
1714 : : "foo (foo (x))". */
1715 : :
1716 : : static void
1717 : 36 : print_nested_fn (FILE* stream, const char *fname, const char* arg,
1718 : : unsigned int n)
1719 : : {
1720 : 36 : if (n == 0)
1721 : 10 : fprintf (stream, "%s", arg);
1722 : : else
1723 : : {
1724 : 26 : fprintf (stream, "%s (", fname);
1725 : 26 : print_nested_fn (stream, fname, arg, n - 1);
1726 : 26 : fprintf (stream, ")");
1727 : : }
1728 : 36 : }
1729 : :
1730 : : /* Print to STREAM the fractional sequence of sqrt chains
1731 : : applied to ARG, described by INFO. Used for the dump file. */
1732 : :
1733 : : static void
1734 : 7 : dump_fractional_sqrt_sequence (FILE *stream, const char *arg,
1735 : : struct pow_synth_sqrt_info *info)
1736 : : {
1737 : 29 : for (unsigned int i = 0; i < info->deepest; i++)
1738 : : {
1739 : 22 : bool is_set = info->factors[i];
1740 : 22 : if (is_set)
1741 : : {
1742 : 10 : print_nested_fn (stream, "sqrt", arg, i + 1);
1743 : 10 : if (i != info->deepest - 1)
1744 : 3 : fprintf (stream, " * ");
1745 : : }
1746 : : }
1747 : 7 : }
1748 : :
1749 : : /* Print to STREAM a representation of raising ARG to an integer
1750 : : power N. Used for the dump file. */
1751 : :
1752 : : static void
1753 : 7 : dump_integer_part (FILE *stream, const char* arg, HOST_WIDE_INT n)
1754 : : {
1755 : 7 : if (n > 1)
1756 : 3 : fprintf (stream, "powi (%s, " HOST_WIDE_INT_PRINT_DEC ")", arg, n);
1757 : 4 : else if (n == 1)
1758 : 3 : fprintf (stream, "%s", arg);
1759 : 7 : }
1760 : :
1761 : : /* Attempt to synthesize a POW[F] (ARG0, ARG1) call using chains of
1762 : : square roots. Place at GSI and LOC. Limit the maximum depth
1763 : : of the sqrt chains to MAX_DEPTH. Return the tree holding the
1764 : : result of the expanded sequence or NULL_TREE if the expansion failed.
1765 : :
1766 : : This routine assumes that ARG1 is a real number with a fractional part
1767 : : (the integer exponent case will have been handled earlier in
1768 : : gimple_expand_builtin_pow).
1769 : :
1770 : : For ARG1 > 0.0:
1771 : : * For ARG1 composed of a whole part WHOLE_PART and a fractional part
1772 : : FRAC_PART i.e. WHOLE_PART == floor (ARG1) and
1773 : : FRAC_PART == ARG1 - WHOLE_PART:
1774 : : Produce POWI (ARG0, WHOLE_PART) * POW (ARG0, FRAC_PART) where
1775 : : POW (ARG0, FRAC_PART) is expanded as a product of square root chains
1776 : : if it can be expressed as such, that is if FRAC_PART satisfies:
1777 : : FRAC_PART == <SUM from i = 1 until MAX_DEPTH> (a[i] * (0.5**i))
1778 : : where integer a[i] is either 0 or 1.
1779 : :
1780 : : Example:
1781 : : POW (x, 3.625) == POWI (x, 3) * POW (x, 0.625)
1782 : : --> POWI (x, 3) * SQRT (x) * SQRT (SQRT (SQRT (x)))
1783 : :
1784 : : For ARG1 < 0.0 there are two approaches:
1785 : : * (A) Expand to 1.0 / POW (ARG0, -ARG1) where POW (ARG0, -ARG1)
1786 : : is calculated as above.
1787 : :
1788 : : Example:
1789 : : POW (x, -5.625) == 1.0 / POW (x, 5.625)
1790 : : --> 1.0 / (POWI (x, 5) * SQRT (x) * SQRT (SQRT (SQRT (x))))
1791 : :
1792 : : * (B) : WHOLE_PART := - ceil (abs (ARG1))
1793 : : FRAC_PART := ARG1 - WHOLE_PART
1794 : : and expand to POW (x, FRAC_PART) / POWI (x, WHOLE_PART).
1795 : : Example:
1796 : : POW (x, -5.875) == POW (x, 0.125) / POWI (X, 6)
1797 : : --> SQRT (SQRT (SQRT (x))) / (POWI (x, 6))
1798 : :
1799 : : For ARG1 < 0.0 we choose between (A) and (B) depending on
1800 : : how many multiplications we'd have to do.
1801 : : So, for the example in (B): POW (x, -5.875), if we were to
1802 : : follow algorithm (A) we would produce:
1803 : : 1.0 / POWI (X, 5) * SQRT (X) * SQRT (SQRT (X)) * SQRT (SQRT (SQRT (X)))
1804 : : which contains more multiplications than approach (B).
1805 : :
1806 : : Hopefully, this approach will eliminate potentially expensive POW library
1807 : : calls when unsafe floating point math is enabled and allow the compiler to
1808 : : further optimise the multiplies, square roots and divides produced by this
1809 : : function. */
1810 : :
1811 : : static tree
1812 : 26 : expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
1813 : : tree arg0, tree arg1, HOST_WIDE_INT max_depth)
1814 : : {
1815 : 26 : tree type = TREE_TYPE (arg0);
1816 : 26 : machine_mode mode = TYPE_MODE (type);
1817 : 26 : tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
1818 : 26 : bool one_over = true;
1819 : :
1820 : 26 : if (!sqrtfn)
1821 : : return NULL_TREE;
1822 : :
1823 : 26 : if (TREE_CODE (arg1) != REAL_CST)
1824 : : return NULL_TREE;
1825 : :
1826 : 26 : REAL_VALUE_TYPE exp_init = TREE_REAL_CST (arg1);
1827 : :
1828 : 26 : gcc_assert (max_depth > 0);
1829 : 26 : tree *cache = XALLOCAVEC (tree, max_depth + 1);
1830 : :
1831 : 26 : struct pow_synth_sqrt_info synth_info;
1832 : 26 : synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
1833 : 26 : synth_info.deepest = 0;
1834 : 26 : synth_info.num_mults = 0;
1835 : :
1836 : 26 : bool neg_exp = REAL_VALUE_NEGATIVE (exp_init);
1837 : 26 : REAL_VALUE_TYPE exp = real_value_abs (&exp_init);
1838 : :
1839 : : /* The whole and fractional parts of exp. */
1840 : 26 : REAL_VALUE_TYPE whole_part;
1841 : 26 : REAL_VALUE_TYPE frac_part;
1842 : :
1843 : 26 : real_floor (&whole_part, mode, &exp);
1844 : 26 : real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
1845 : :
1846 : :
1847 : 26 : REAL_VALUE_TYPE ceil_whole = dconst0;
1848 : 26 : REAL_VALUE_TYPE ceil_fract = dconst0;
1849 : :
1850 : 26 : if (neg_exp)
1851 : : {
1852 : 10 : real_ceil (&ceil_whole, mode, &exp);
1853 : 10 : real_arithmetic (&ceil_fract, MINUS_EXPR, &ceil_whole, &exp);
1854 : : }
1855 : :
1856 : 26 : if (!representable_as_half_series_p (frac_part, max_depth, &synth_info))
1857 : : return NULL_TREE;
1858 : :
1859 : : /* Check whether it's more profitable to not use 1.0 / ... */
1860 : 19 : if (neg_exp)
1861 : : {
1862 : 8 : struct pow_synth_sqrt_info alt_synth_info;
1863 : 8 : alt_synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
1864 : 8 : alt_synth_info.deepest = 0;
1865 : 8 : alt_synth_info.num_mults = 0;
1866 : :
1867 : 8 : if (representable_as_half_series_p (ceil_fract, max_depth,
1868 : : &alt_synth_info)
1869 : 8 : && alt_synth_info.deepest <= synth_info.deepest
1870 : 16 : && alt_synth_info.num_mults < synth_info.num_mults)
1871 : : {
1872 : 2 : whole_part = ceil_whole;
1873 : 2 : frac_part = ceil_fract;
1874 : 2 : synth_info.deepest = alt_synth_info.deepest;
1875 : 2 : synth_info.num_mults = alt_synth_info.num_mults;
1876 : 2 : memcpy (synth_info.factors, alt_synth_info.factors,
1877 : : (max_depth + 1) * sizeof (bool));
1878 : 2 : one_over = false;
1879 : : }
1880 : : }
1881 : :
1882 : 19 : HOST_WIDE_INT n = real_to_integer (&whole_part);
1883 : 19 : REAL_VALUE_TYPE cint;
1884 : 19 : real_from_integer (&cint, VOIDmode, n, SIGNED);
1885 : :
1886 : 19 : if (!real_identical (&whole_part, &cint))
1887 : : return NULL_TREE;
1888 : :
1889 : 19 : if (powi_cost (n) + synth_info.num_mults > POWI_MAX_MULTS)
1890 : : return NULL_TREE;
1891 : :
1892 : 19 : memset (cache, 0, (max_depth + 1) * sizeof (tree));
1893 : :
1894 : 19 : tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
1895 : :
1896 : : /* Calculate the integer part of the exponent. */
1897 : 19 : if (n > 1)
1898 : : {
1899 : 7 : integer_res = gimple_expand_builtin_powi (gsi, loc, arg0, n);
1900 : 7 : if (!integer_res)
1901 : : return NULL_TREE;
1902 : : }
1903 : :
1904 : 19 : if (dump_file)
1905 : : {
1906 : 7 : char string[64];
1907 : :
1908 : 7 : real_to_decimal (string, &exp_init, sizeof (string), 0, 1);
1909 : 7 : fprintf (dump_file, "synthesizing pow (x, %s) as:\n", string);
1910 : :
1911 : 7 : if (neg_exp)
1912 : : {
1913 : 2 : if (one_over)
1914 : : {
1915 : 1 : fprintf (dump_file, "1.0 / (");
1916 : 1 : dump_integer_part (dump_file, "x", n);
1917 : 1 : if (n > 0)
1918 : 1 : fprintf (dump_file, " * ");
1919 : 1 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1920 : 1 : fprintf (dump_file, ")");
1921 : : }
1922 : : else
1923 : : {
1924 : 1 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1925 : 1 : fprintf (dump_file, " / (");
1926 : 1 : dump_integer_part (dump_file, "x", n);
1927 : 1 : fprintf (dump_file, ")");
1928 : : }
1929 : : }
1930 : : else
1931 : : {
1932 : 5 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1933 : 5 : if (n > 0)
1934 : 4 : fprintf (dump_file, " * ");
1935 : 5 : dump_integer_part (dump_file, "x", n);
1936 : : }
1937 : :
1938 : 7 : fprintf (dump_file, "\ndeepest sqrt chain: %d\n", synth_info.deepest);
1939 : : }
1940 : :
1941 : :
1942 : 19 : tree fract_res = NULL_TREE;
1943 : 19 : cache[0] = arg0;
1944 : :
1945 : : /* Calculate the fractional part of the exponent. */
1946 : 60 : for (unsigned i = 0; i < synth_info.deepest; i++)
1947 : : {
1948 : 41 : if (synth_info.factors[i])
1949 : : {
1950 : 24 : tree sqrt_chain = get_fn_chain (arg0, i + 1, gsi, sqrtfn, loc, cache);
1951 : :
1952 : 24 : if (!fract_res)
1953 : : fract_res = sqrt_chain;
1954 : :
1955 : : else
1956 : 5 : fract_res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1957 : : fract_res, sqrt_chain);
1958 : : }
1959 : : }
1960 : :
1961 : 19 : tree res = NULL_TREE;
1962 : :
1963 : 19 : if (neg_exp)
1964 : : {
1965 : 8 : if (one_over)
1966 : : {
1967 : 6 : if (n > 0)
1968 : 4 : res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1969 : : fract_res, integer_res);
1970 : : else
1971 : : res = fract_res;
1972 : :
1973 : 6 : res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
1974 : : build_real (type, dconst1), res);
1975 : : }
1976 : : else
1977 : : {
1978 : 2 : res = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
1979 : : fract_res, integer_res);
1980 : : }
1981 : : }
1982 : : else
1983 : 11 : res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1984 : : fract_res, integer_res);
1985 : : return res;
1986 : : }
1987 : :
1988 : : /* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
1989 : : with location info LOC. If possible, create an equivalent and
1990 : : less expensive sequence of statements prior to GSI, and return an
1991 : : expession holding the result. */
1992 : :
1993 : : static tree
1994 : 590 : gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
1995 : : tree arg0, tree arg1)
1996 : : {
1997 : 590 : REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
1998 : 590 : REAL_VALUE_TYPE c2, dconst3;
1999 : 590 : HOST_WIDE_INT n;
2000 : 590 : tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
2001 : 590 : machine_mode mode;
2002 : 590 : bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
2003 : 590 : bool hw_sqrt_exists, c_is_int, c2_is_int;
2004 : :
2005 : 590 : dconst1_4 = dconst1;
2006 : 590 : SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
2007 : :
2008 : : /* If the exponent isn't a constant, there's nothing of interest
2009 : : to be done. */
2010 : 590 : if (TREE_CODE (arg1) != REAL_CST)
2011 : : return NULL_TREE;
2012 : :
2013 : : /* Don't perform the operation if flag_signaling_nans is on
2014 : : and the operand is a signaling NaN. */
2015 : 355 : if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
2016 : 355 : && ((TREE_CODE (arg0) == REAL_CST
2017 : 0 : && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0)))
2018 : 1 : || REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1))))
2019 : 0 : return NULL_TREE;
2020 : :
2021 : : /* If the exponent is equivalent to an integer, expand to an optimal
2022 : : multiplication sequence when profitable. */
2023 : 355 : c = TREE_REAL_CST (arg1);
2024 : 355 : n = real_to_integer (&c);
2025 : 355 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2026 : 355 : c_is_int = real_identical (&c, &cint);
2027 : :
2028 : 355 : if (c_is_int
2029 : 355 : && ((n >= -1 && n <= 2)
2030 : 66 : || (flag_unsafe_math_optimizations
2031 : 11 : && speed_p
2032 : 11 : && powi_cost (n) <= POWI_MAX_MULTS)))
2033 : 51 : return gimple_expand_builtin_powi (gsi, loc, arg0, n);
2034 : :
2035 : : /* Attempt various optimizations using sqrt and cbrt. */
2036 : 304 : type = TREE_TYPE (arg0);
2037 : 304 : mode = TYPE_MODE (type);
2038 : 304 : sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
2039 : :
2040 : : /* Optimize pow(x,0.5) = sqrt(x). This replacement is always safe
2041 : : unless signed zeros must be maintained. pow(-0,0.5) = +0, while
2042 : : sqrt(-0) = -0. */
2043 : 304 : if (sqrtfn
2044 : 304 : && real_equal (&c, &dconsthalf)
2045 : 312 : && !HONOR_SIGNED_ZEROS (mode))
2046 : 0 : return build_and_insert_call (gsi, loc, sqrtfn, arg0);
2047 : :
2048 : 304 : hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing;
2049 : :
2050 : : /* Optimize pow(x,1./3.) = cbrt(x). This requires unsafe math
2051 : : optimizations since 1./3. is not exactly representable. If x
2052 : : is negative and finite, the correct value of pow(x,1./3.) is
2053 : : a NaN with the "invalid" exception raised, because the value
2054 : : of 1./3. actually has an even denominator. The correct value
2055 : : of cbrt(x) is a negative real value. */
2056 : 304 : cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
2057 : 304 : dconst1_3 = real_value_truncate (mode, dconst_third ());
2058 : :
2059 : 304 : if (flag_unsafe_math_optimizations
2060 : 26 : && cbrtfn
2061 : 26 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2062 : 330 : && real_equal (&c, &dconst1_3))
2063 : 0 : return build_and_insert_call (gsi, loc, cbrtfn, arg0);
2064 : :
2065 : : /* Optimize pow(x,1./6.) = cbrt(sqrt(x)). Don't do this optimization
2066 : : if we don't have a hardware sqrt insn. */
2067 : 304 : dconst1_6 = dconst1_3;
2068 : 304 : SET_REAL_EXP (&dconst1_6, REAL_EXP (&dconst1_6) - 1);
2069 : :
2070 : 304 : if (flag_unsafe_math_optimizations
2071 : 26 : && sqrtfn
2072 : 26 : && cbrtfn
2073 : 26 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2074 : : && speed_p
2075 : 26 : && hw_sqrt_exists
2076 : 330 : && real_equal (&c, &dconst1_6))
2077 : : {
2078 : : /* sqrt(x) */
2079 : 0 : sqrt_arg0 = build_and_insert_call (gsi, loc, sqrtfn, arg0);
2080 : :
2081 : : /* cbrt(sqrt(x)) */
2082 : 0 : return build_and_insert_call (gsi, loc, cbrtfn, sqrt_arg0);
2083 : : }
2084 : :
2085 : :
2086 : : /* Attempt to expand the POW as a product of square root chains.
2087 : : Expand the 0.25 case even when otpimising for size. */
2088 : 304 : if (flag_unsafe_math_optimizations
2089 : 26 : && sqrtfn
2090 : 26 : && hw_sqrt_exists
2091 : 26 : && (speed_p || real_equal (&c, &dconst1_4))
2092 : 330 : && !HONOR_SIGNED_ZEROS (mode))
2093 : : {
2094 : 52 : unsigned int max_depth = speed_p
2095 : 26 : ? param_max_pow_sqrt_depth
2096 : : : 2;
2097 : :
2098 : 26 : tree expand_with_sqrts
2099 : 26 : = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth);
2100 : :
2101 : 26 : if (expand_with_sqrts)
2102 : : return expand_with_sqrts;
2103 : : }
2104 : :
2105 : 285 : real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2106 : 285 : n = real_to_integer (&c2);
2107 : 285 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2108 : 285 : c2_is_int = real_identical (&c2, &cint);
2109 : :
2110 : : /* Optimize pow(x,c), where 3c = n for some nonzero integer n, into
2111 : :
2112 : : powi(x, n/3) * powi(cbrt(x), n%3), n > 0;
2113 : : 1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)), n < 0.
2114 : :
2115 : : Do not calculate the first factor when n/3 = 0. As cbrt(x) is
2116 : : different from pow(x, 1./3.) due to rounding and behavior with
2117 : : negative x, we need to constrain this transformation to unsafe
2118 : : math and positive x or finite math. */
2119 : 285 : real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
2120 : 285 : real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2121 : 285 : real_round (&c2, mode, &c2);
2122 : 285 : n = real_to_integer (&c2);
2123 : 285 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2124 : 285 : real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2125 : 285 : real_convert (&c2, mode, &c2);
2126 : :
2127 : 285 : if (flag_unsafe_math_optimizations
2128 : 7 : && cbrtfn
2129 : 7 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2130 : 7 : && real_identical (&c2, &c)
2131 : 4 : && !c2_is_int
2132 : 4 : && optimize_function_for_speed_p (cfun)
2133 : 289 : && powi_cost (n / 3) <= POWI_MAX_MULTS)
2134 : : {
2135 : 4 : tree powi_x_ndiv3 = NULL_TREE;
2136 : :
2137 : : /* Attempt to fold powi(arg0, abs(n/3)) into multiplies. If not
2138 : : possible or profitable, give up. Skip the degenerate case when
2139 : : abs(n) < 3, where the result is always 1. */
2140 : 4 : if (absu_hwi (n) >= 3)
2141 : : {
2142 : 4 : powi_x_ndiv3 = gimple_expand_builtin_powi (gsi, loc, arg0,
2143 : : abs_hwi (n / 3));
2144 : 4 : if (!powi_x_ndiv3)
2145 : : return NULL_TREE;
2146 : : }
2147 : :
2148 : : /* Calculate powi(cbrt(x), n%3). Don't use gimple_expand_builtin_powi
2149 : : as that creates an unnecessary variable. Instead, just produce
2150 : : either cbrt(x) or cbrt(x) * cbrt(x). */
2151 : 4 : cbrt_x = build_and_insert_call (gsi, loc, cbrtfn, arg0);
2152 : :
2153 : 4 : if (absu_hwi (n) % 3 == 1)
2154 : : powi_cbrt_x = cbrt_x;
2155 : : else
2156 : 2 : powi_cbrt_x = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
2157 : : cbrt_x, cbrt_x);
2158 : :
2159 : : /* Multiply the two subexpressions, unless powi(x,abs(n)/3) = 1. */
2160 : 4 : if (absu_hwi (n) < 3)
2161 : : result = powi_cbrt_x;
2162 : : else
2163 : 4 : result = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
2164 : : powi_x_ndiv3, powi_cbrt_x);
2165 : :
2166 : : /* If n is negative, reciprocate the result. */
2167 : 4 : if (n < 0)
2168 : 1 : result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
2169 : : build_real (type, dconst1), result);
2170 : :
2171 : 4 : return result;
2172 : : }
2173 : :
2174 : : /* No optimizations succeeded. */
2175 : : return NULL_TREE;
2176 : : }
2177 : :
2178 : : /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
2179 : : on the SSA_NAME argument of each of them. */
2180 : :
2181 : : namespace {
2182 : :
2183 : : const pass_data pass_data_cse_sincos =
2184 : : {
2185 : : GIMPLE_PASS, /* type */
2186 : : "sincos", /* name */
2187 : : OPTGROUP_NONE, /* optinfo_flags */
2188 : : TV_TREE_SINCOS, /* tv_id */
2189 : : PROP_ssa, /* properties_required */
2190 : : 0, /* properties_provided */
2191 : : 0, /* properties_destroyed */
2192 : : 0, /* todo_flags_start */
2193 : : TODO_update_ssa, /* todo_flags_finish */
2194 : : };
2195 : :
2196 : : class pass_cse_sincos : public gimple_opt_pass
2197 : : {
2198 : : public:
2199 : 289080 : pass_cse_sincos (gcc::context *ctxt)
2200 : 578160 : : gimple_opt_pass (pass_data_cse_sincos, ctxt)
2201 : : {}
2202 : :
2203 : : /* opt_pass methods: */
2204 : 1035897 : bool gate (function *) final override
2205 : : {
2206 : 1035897 : return optimize;
2207 : : }
2208 : :
2209 : : unsigned int execute (function *) final override;
2210 : :
2211 : : }; // class pass_cse_sincos
2212 : :
2213 : : unsigned int
2214 : 1035874 : pass_cse_sincos::execute (function *fun)
2215 : : {
2216 : 1035874 : basic_block bb;
2217 : 1035874 : bool cfg_changed = false;
2218 : :
2219 : 1035874 : calculate_dominance_info (CDI_DOMINATORS);
2220 : 1035874 : memset (&sincos_stats, 0, sizeof (sincos_stats));
2221 : :
2222 : 11407491 : FOR_EACH_BB_FN (bb, fun)
2223 : : {
2224 : 10371617 : gimple_stmt_iterator gsi;
2225 : :
2226 : 94066883 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2227 : : {
2228 : 83695266 : gimple *stmt = gsi_stmt (gsi);
2229 : :
2230 : 83695266 : if (is_gimple_call (stmt)
2231 : 83695266 : && gimple_call_lhs (stmt))
2232 : : {
2233 : 2034433 : tree arg;
2234 : 2034433 : switch (gimple_call_combined_fn (stmt))
2235 : : {
2236 : 1030 : CASE_CFN_COS:
2237 : 1030 : CASE_CFN_SIN:
2238 : 1030 : CASE_CFN_CEXPI:
2239 : 1030 : arg = gimple_call_arg (stmt, 0);
2240 : : /* Make sure we have either sincos or cexp. */
2241 : 1030 : if (!targetm.libc_has_function (function_c99_math_complex,
2242 : 1030 : TREE_TYPE (arg))
2243 : 1030 : && !targetm.libc_has_function (function_sincos,
2244 : 0 : TREE_TYPE (arg)))
2245 : : break;
2246 : :
2247 : 1030 : if (TREE_CODE (arg) == SSA_NAME)
2248 : 1030 : cfg_changed |= execute_cse_sincos_1 (arg);
2249 : : break;
2250 : : default:
2251 : : break;
2252 : : }
2253 : : }
2254 : : }
2255 : : }
2256 : :
2257 : 1035874 : statistics_counter_event (fun, "sincos statements inserted",
2258 : : sincos_stats.inserted);
2259 : 1035874 : statistics_counter_event (fun, "conv statements removed",
2260 : : sincos_stats.conv_removed);
2261 : :
2262 : 1035874 : return cfg_changed ? TODO_cleanup_cfg : 0;
2263 : : }
2264 : :
2265 : : } // anon namespace
2266 : :
2267 : : gimple_opt_pass *
2268 : 289080 : make_pass_cse_sincos (gcc::context *ctxt)
2269 : : {
2270 : 289080 : return new pass_cse_sincos (ctxt);
2271 : : }
2272 : :
2273 : : /* Expand powi(x,n) into an optimal number of multiplies, when n is a
2274 : : constant. */
2275 : : namespace {
2276 : :
2277 : : const pass_data pass_data_expand_pow =
2278 : : {
2279 : : GIMPLE_PASS, /* type */
2280 : : "pow", /* name */
2281 : : OPTGROUP_NONE, /* optinfo_flags */
2282 : : TV_TREE_POW, /* tv_id */
2283 : : PROP_ssa, /* properties_required */
2284 : : PROP_gimple_opt_math, /* properties_provided */
2285 : : 0, /* properties_destroyed */
2286 : : 0, /* todo_flags_start */
2287 : : TODO_update_ssa, /* todo_flags_finish */
2288 : : };
2289 : :
2290 : : class pass_expand_pow : public gimple_opt_pass
2291 : : {
2292 : : public:
2293 : 289080 : pass_expand_pow (gcc::context *ctxt)
2294 : 578160 : : gimple_opt_pass (pass_data_expand_pow, ctxt)
2295 : : {}
2296 : :
2297 : : /* opt_pass methods: */
2298 : 1035897 : bool gate (function *) final override
2299 : : {
2300 : 1035897 : return optimize;
2301 : : }
2302 : :
2303 : : unsigned int execute (function *) final override;
2304 : :
2305 : : }; // class pass_expand_pow
2306 : :
2307 : : unsigned int
2308 : 1035892 : pass_expand_pow::execute (function *fun)
2309 : : {
2310 : 1035892 : basic_block bb;
2311 : 1035892 : bool cfg_changed = false;
2312 : :
2313 : 1035892 : calculate_dominance_info (CDI_DOMINATORS);
2314 : :
2315 : 10617811 : FOR_EACH_BB_FN (bb, fun)
2316 : : {
2317 : 9581919 : gimple_stmt_iterator gsi;
2318 : 9581919 : bool cleanup_eh = false;
2319 : :
2320 : 91185929 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2321 : : {
2322 : 81604010 : gimple *stmt = gsi_stmt (gsi);
2323 : :
2324 : : /* Only the last stmt in a bb could throw, no need to call
2325 : : gimple_purge_dead_eh_edges if we change something in the middle
2326 : : of a basic block. */
2327 : 81604010 : cleanup_eh = false;
2328 : :
2329 : 81604010 : if (is_gimple_call (stmt)
2330 : 81604010 : && gimple_call_lhs (stmt))
2331 : : {
2332 : 2009039 : tree arg0, arg1, result;
2333 : 2009039 : HOST_WIDE_INT n;
2334 : 2009039 : location_t loc;
2335 : :
2336 : 2009039 : switch (gimple_call_combined_fn (stmt))
2337 : : {
2338 : 590 : CASE_CFN_POW:
2339 : 590 : arg0 = gimple_call_arg (stmt, 0);
2340 : 590 : arg1 = gimple_call_arg (stmt, 1);
2341 : :
2342 : 590 : loc = gimple_location (stmt);
2343 : 590 : result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
2344 : :
2345 : 590 : if (result)
2346 : : {
2347 : 74 : tree lhs = gimple_get_lhs (stmt);
2348 : 74 : gassign *new_stmt = gimple_build_assign (lhs, result);
2349 : 74 : gimple_set_location (new_stmt, loc);
2350 : 74 : unlink_stmt_vdef (stmt);
2351 : 74 : gsi_replace (&gsi, new_stmt, true);
2352 : 74 : cleanup_eh = true;
2353 : 148 : if (gimple_vdef (stmt))
2354 : 22 : release_ssa_name (gimple_vdef (stmt));
2355 : : }
2356 : : break;
2357 : :
2358 : 806 : CASE_CFN_POWI:
2359 : 806 : arg0 = gimple_call_arg (stmt, 0);
2360 : 806 : arg1 = gimple_call_arg (stmt, 1);
2361 : 806 : loc = gimple_location (stmt);
2362 : :
2363 : 806 : if (real_minus_onep (arg0))
2364 : : {
2365 : 11 : tree t0, t1, cond, one, minus_one;
2366 : 11 : gassign *stmt;
2367 : :
2368 : 11 : t0 = TREE_TYPE (arg0);
2369 : 11 : t1 = TREE_TYPE (arg1);
2370 : 11 : one = build_real (t0, dconst1);
2371 : 11 : minus_one = build_real (t0, dconstm1);
2372 : :
2373 : 11 : cond = make_temp_ssa_name (t1, NULL, "powi_cond");
2374 : 11 : stmt = gimple_build_assign (cond, BIT_AND_EXPR,
2375 : : arg1, build_int_cst (t1, 1));
2376 : 11 : gimple_set_location (stmt, loc);
2377 : 11 : gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2378 : :
2379 : 11 : result = make_temp_ssa_name (t0, NULL, "powi");
2380 : 11 : stmt = gimple_build_assign (result, COND_EXPR, cond,
2381 : : minus_one, one);
2382 : 11 : gimple_set_location (stmt, loc);
2383 : 11 : gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2384 : : }
2385 : : else
2386 : : {
2387 : 795 : if (!tree_fits_shwi_p (arg1))
2388 : : break;
2389 : :
2390 : 584 : n = tree_to_shwi (arg1);
2391 : 584 : result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
2392 : : }
2393 : :
2394 : 595 : if (result)
2395 : : {
2396 : 587 : tree lhs = gimple_get_lhs (stmt);
2397 : 587 : gassign *new_stmt = gimple_build_assign (lhs, result);
2398 : 587 : gimple_set_location (new_stmt, loc);
2399 : 587 : unlink_stmt_vdef (stmt);
2400 : 587 : gsi_replace (&gsi, new_stmt, true);
2401 : 587 : cleanup_eh = true;
2402 : 81605184 : if (gimple_vdef (stmt))
2403 : 0 : release_ssa_name (gimple_vdef (stmt));
2404 : : }
2405 : : break;
2406 : :
2407 : 211 : default:;
2408 : : }
2409 : : }
2410 : : }
2411 : 9581919 : if (cleanup_eh)
2412 : 1 : cfg_changed |= gimple_purge_dead_eh_edges (bb);
2413 : : }
2414 : :
2415 : 1035892 : return cfg_changed ? TODO_cleanup_cfg : 0;
2416 : : }
2417 : :
2418 : : } // anon namespace
2419 : :
2420 : : gimple_opt_pass *
2421 : 289080 : make_pass_expand_pow (gcc::context *ctxt)
2422 : : {
2423 : 289080 : return new pass_expand_pow (ctxt);
2424 : : }
2425 : :
2426 : : /* Return true if stmt is a type conversion operation that can be stripped
2427 : : when used in a widening multiply operation. */
2428 : : static bool
2429 : 448898 : widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
2430 : : {
2431 : 448898 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
2432 : :
2433 : 448898 : if (TREE_CODE (result_type) == INTEGER_TYPE)
2434 : : {
2435 : 448898 : tree op_type;
2436 : 448898 : tree inner_op_type;
2437 : :
2438 : 448898 : if (!CONVERT_EXPR_CODE_P (rhs_code))
2439 : : return false;
2440 : :
2441 : 182845 : op_type = TREE_TYPE (gimple_assign_lhs (stmt));
2442 : :
2443 : : /* If the type of OP has the same precision as the result, then
2444 : : we can strip this conversion. The multiply operation will be
2445 : : selected to create the correct extension as a by-product. */
2446 : 182845 : if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type))
2447 : : return true;
2448 : :
2449 : : /* We can also strip a conversion if it preserves the signed-ness of
2450 : : the operation and doesn't narrow the range. */
2451 : 1162 : inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
2452 : :
2453 : : /* If the inner-most type is unsigned, then we can strip any
2454 : : intermediate widening operation. If it's signed, then the
2455 : : intermediate widening operation must also be signed. */
2456 : 1162 : if ((TYPE_UNSIGNED (inner_op_type)
2457 : 1161 : || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type))
2458 : 2323 : && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type))
2459 : : return true;
2460 : :
2461 : 1162 : return false;
2462 : : }
2463 : :
2464 : 0 : return rhs_code == FIXED_CONVERT_EXPR;
2465 : : }
2466 : :
2467 : : /* Return true if RHS is a suitable operand for a widening multiplication,
2468 : : assuming a target type of TYPE.
2469 : : There are two cases:
2470 : :
2471 : : - RHS makes some value at least twice as wide. Store that value
2472 : : in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.
2473 : :
2474 : : - RHS is an integer constant. Store that value in *NEW_RHS_OUT if so,
2475 : : but leave *TYPE_OUT untouched. */
2476 : :
2477 : : static bool
2478 : 905862 : is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
2479 : : tree *new_rhs_out)
2480 : : {
2481 : 905862 : gimple *stmt;
2482 : 905862 : tree type1, rhs1;
2483 : :
2484 : 905862 : if (TREE_CODE (rhs) == SSA_NAME)
2485 : : {
2486 : : /* Use tree_non_zero_bits to see if this operand is zero_extended
2487 : : for unsigned widening multiplications or non-negative for
2488 : : signed widening multiplications. */
2489 : 748068 : if (TREE_CODE (type) == INTEGER_TYPE
2490 : 748068 : && (TYPE_PRECISION (type) & 1) == 0
2491 : 1496136 : && int_mode_for_size (TYPE_PRECISION (type) / 2, 1).exists ())
2492 : : {
2493 : 742266 : unsigned int prec = TYPE_PRECISION (type);
2494 : 742266 : unsigned int hprec = prec / 2;
2495 : 742266 : wide_int bits = wide_int::from (tree_nonzero_bits (rhs), prec,
2496 : 1484532 : TYPE_SIGN (TREE_TYPE (rhs)));
2497 : 742266 : if (TYPE_UNSIGNED (type)
2498 : 1290280 : && wi::bit_and (bits, wi::mask (hprec, true, prec)) == 0)
2499 : : {
2500 : 148232 : *type_out = build_nonstandard_integer_type (hprec, true);
2501 : : /* X & MODE_MASK can be simplified to (T)X. */
2502 : 148232 : stmt = SSA_NAME_DEF_STMT (rhs);
2503 : 296464 : if (is_gimple_assign (stmt)
2504 : 129233 : && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
2505 : 16921 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
2506 : 181474 : && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
2507 : 16621 : prec, TYPE_SIGN (TREE_TYPE (rhs)))
2508 : 198095 : == wi::mask (hprec, false, prec))
2509 : 14835 : *new_rhs_out = gimple_assign_rhs1 (stmt);
2510 : : else
2511 : 133397 : *new_rhs_out = rhs;
2512 : 148232 : return true;
2513 : : }
2514 : 594034 : else if (!TYPE_UNSIGNED (type)
2515 : 788286 : && wi::bit_and (bits, wi::mask (hprec - 1, true, prec)) == 0)
2516 : : {
2517 : 26559 : *type_out = build_nonstandard_integer_type (hprec, false);
2518 : 26559 : *new_rhs_out = rhs;
2519 : 26559 : return true;
2520 : : }
2521 : 742266 : }
2522 : :
2523 : 573277 : stmt = SSA_NAME_DEF_STMT (rhs);
2524 : 573277 : if (is_gimple_assign (stmt))
2525 : : {
2526 : :
2527 : 448898 : if (widening_mult_conversion_strippable_p (type, stmt))
2528 : : {
2529 : 181683 : rhs1 = gimple_assign_rhs1 (stmt);
2530 : :
2531 : 181683 : if (TREE_CODE (rhs1) == INTEGER_CST)
2532 : : {
2533 : 0 : *new_rhs_out = rhs1;
2534 : 0 : *type_out = NULL;
2535 : 0 : return true;
2536 : : }
2537 : : }
2538 : : else
2539 : : rhs1 = rhs;
2540 : : }
2541 : : else
2542 : : rhs1 = rhs;
2543 : :
2544 : 573277 : type1 = TREE_TYPE (rhs1);
2545 : :
2546 : 573277 : if (TREE_CODE (type1) != TREE_CODE (type)
2547 : 573277 : || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
2548 : : return false;
2549 : :
2550 : 58124 : *new_rhs_out = rhs1;
2551 : 58124 : *type_out = type1;
2552 : 58124 : return true;
2553 : : }
2554 : :
2555 : 157794 : if (TREE_CODE (rhs) == INTEGER_CST)
2556 : : {
2557 : 157794 : *new_rhs_out = rhs;
2558 : 157794 : *type_out = NULL;
2559 : 157794 : return true;
2560 : : }
2561 : :
2562 : : return false;
2563 : : }
2564 : :
2565 : : /* Return true if STMT performs a widening multiplication, assuming the
2566 : : output type is TYPE. If so, store the unwidened types of the operands
2567 : : in *TYPE1_OUT and *TYPE2_OUT respectively. Also fill *RHS1_OUT and
2568 : : *RHS2_OUT such that converting those operands to types *TYPE1_OUT
2569 : : and *TYPE2_OUT would give the operands of the multiplication. */
2570 : :
2571 : : static bool
2572 : 707600 : is_widening_mult_p (gimple *stmt,
2573 : : tree *type1_out, tree *rhs1_out,
2574 : : tree *type2_out, tree *rhs2_out)
2575 : : {
2576 : 707600 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
2577 : :
2578 : 707600 : if (TREE_CODE (type) == INTEGER_TYPE)
2579 : : {
2580 : 707600 : if (TYPE_OVERFLOW_TRAPS (type))
2581 : : return false;
2582 : : }
2583 : 0 : else if (TREE_CODE (type) != FIXED_POINT_TYPE)
2584 : : return false;
2585 : :
2586 : 707572 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
2587 : : rhs1_out))
2588 : : return false;
2589 : :
2590 : 198290 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
2591 : : rhs2_out))
2592 : : return false;
2593 : :
2594 : 192419 : if (*type1_out == NULL)
2595 : : {
2596 : 0 : if (*type2_out == NULL || !int_fits_type_p (*rhs1_out, *type2_out))
2597 : : return false;
2598 : 0 : *type1_out = *type2_out;
2599 : : }
2600 : :
2601 : 192419 : if (*type2_out == NULL)
2602 : : {
2603 : 157794 : if (!int_fits_type_p (*rhs2_out, *type1_out))
2604 : : return false;
2605 : 153089 : *type2_out = *type1_out;
2606 : : }
2607 : :
2608 : : /* Ensure that the larger of the two operands comes first. */
2609 : 187714 : if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out))
2610 : : {
2611 : 91 : std::swap (*type1_out, *type2_out);
2612 : 91 : std::swap (*rhs1_out, *rhs2_out);
2613 : : }
2614 : :
2615 : : return true;
2616 : : }
2617 : :
2618 : : /* Check to see if the CALL statement is an invocation of copysign
2619 : : with 1. being the first argument. */
2620 : : static bool
2621 : 161270 : is_copysign_call_with_1 (gimple *call)
2622 : : {
2623 : 166350 : gcall *c = dyn_cast <gcall *> (call);
2624 : 5136 : if (! c)
2625 : : return false;
2626 : :
2627 : 5136 : enum combined_fn code = gimple_call_combined_fn (c);
2628 : :
2629 : 5136 : if (code == CFN_LAST)
2630 : : return false;
2631 : :
2632 : 4223 : if (builtin_fn_p (code))
2633 : : {
2634 : 1197 : switch (as_builtin_fn (code))
2635 : : {
2636 : 30 : CASE_FLT_FN (BUILT_IN_COPYSIGN):
2637 : 30 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
2638 : 30 : return real_onep (gimple_call_arg (c, 0));
2639 : : default:
2640 : : return false;
2641 : : }
2642 : : }
2643 : :
2644 : 3026 : if (internal_fn_p (code))
2645 : : {
2646 : 3026 : switch (as_internal_fn (code))
2647 : : {
2648 : 26 : case IFN_COPYSIGN:
2649 : 26 : return real_onep (gimple_call_arg (c, 0));
2650 : : default:
2651 : : return false;
2652 : : }
2653 : : }
2654 : :
2655 : : return false;
2656 : : }
2657 : :
2658 : : /* Try to expand the pattern x * copysign (1, y) into xorsign (x, y).
2659 : : This only happens when the xorsign optab is defined, if the
2660 : : pattern is not a xorsign pattern or if expansion fails FALSE is
2661 : : returned, otherwise TRUE is returned. */
2662 : : static bool
2663 : 699520 : convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
2664 : : {
2665 : 699520 : tree treeop0, treeop1, lhs, type;
2666 : 699520 : location_t loc = gimple_location (stmt);
2667 : 699520 : lhs = gimple_assign_lhs (stmt);
2668 : 699520 : treeop0 = gimple_assign_rhs1 (stmt);
2669 : 699520 : treeop1 = gimple_assign_rhs2 (stmt);
2670 : 699520 : type = TREE_TYPE (lhs);
2671 : 699520 : machine_mode mode = TYPE_MODE (type);
2672 : :
2673 : 699520 : if (HONOR_SNANS (type))
2674 : : return false;
2675 : :
2676 : 699428 : if (TREE_CODE (treeop0) == SSA_NAME && TREE_CODE (treeop1) == SSA_NAME)
2677 : : {
2678 : 209401 : gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
2679 : 209401 : if (!has_single_use (treeop0) || !is_copysign_call_with_1 (call0))
2680 : : {
2681 : 209375 : call0 = SSA_NAME_DEF_STMT (treeop1);
2682 : 209375 : if (!has_single_use (treeop1) || !is_copysign_call_with_1 (call0))
2683 : 209355 : return false;
2684 : :
2685 : : treeop1 = treeop0;
2686 : : }
2687 : 46 : if (optab_handler (xorsign_optab, mode) == CODE_FOR_nothing)
2688 : : return false;
2689 : :
2690 : 46 : gcall *c = as_a<gcall*> (call0);
2691 : 46 : treeop0 = gimple_call_arg (c, 1);
2692 : :
2693 : 46 : gcall *call_stmt
2694 : 46 : = gimple_build_call_internal (IFN_XORSIGN, 2, treeop1, treeop0);
2695 : 46 : gimple_set_lhs (call_stmt, lhs);
2696 : 46 : gimple_set_location (call_stmt, loc);
2697 : 46 : gsi_replace (gsi, call_stmt, true);
2698 : 46 : return true;
2699 : : }
2700 : :
2701 : : return false;
2702 : : }
2703 : :
2704 : : /* Process a single gimple statement STMT, which has a MULT_EXPR as
2705 : : its rhs, and try to convert it into a WIDEN_MULT_EXPR. The return
2706 : : value is true iff we converted the statement. */
2707 : :
2708 : : static bool
2709 : 709808 : convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
2710 : : {
2711 : 709808 : tree lhs, rhs1, rhs2, type, type1, type2;
2712 : 709808 : enum insn_code handler;
2713 : 709808 : scalar_int_mode to_mode, from_mode, actual_mode;
2714 : 709808 : optab op;
2715 : 709808 : int actual_precision;
2716 : 709808 : location_t loc = gimple_location (stmt);
2717 : 709808 : bool from_unsigned1, from_unsigned2;
2718 : :
2719 : 709808 : lhs = gimple_assign_lhs (stmt);
2720 : 709808 : type = TREE_TYPE (lhs);
2721 : 709808 : if (TREE_CODE (type) != INTEGER_TYPE)
2722 : : return false;
2723 : :
2724 : 574720 : if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))
2725 : : return false;
2726 : :
2727 : : /* if any one of rhs1 and rhs2 is subject to abnormal coalescing,
2728 : : avoid the tranform. */
2729 : 152786 : if ((TREE_CODE (rhs1) == SSA_NAME
2730 : 152786 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2731 : 305571 : || (TREE_CODE (rhs2) == SSA_NAME
2732 : 24141 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)))
2733 : : return false;
2734 : :
2735 : 152785 : to_mode = SCALAR_INT_TYPE_MODE (type);
2736 : 152785 : from_mode = SCALAR_INT_TYPE_MODE (type1);
2737 : 152785 : if (to_mode == from_mode)
2738 : : return false;
2739 : :
2740 : 152781 : from_unsigned1 = TYPE_UNSIGNED (type1);
2741 : 152781 : from_unsigned2 = TYPE_UNSIGNED (type2);
2742 : :
2743 : 152781 : if (from_unsigned1 && from_unsigned2)
2744 : : op = umul_widen_optab;
2745 : 56776 : else if (!from_unsigned1 && !from_unsigned2)
2746 : : op = smul_widen_optab;
2747 : : else
2748 : 1911 : op = usmul_widen_optab;
2749 : :
2750 : 152781 : handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
2751 : : &actual_mode);
2752 : :
2753 : 152781 : if (handler == CODE_FOR_nothing)
2754 : : {
2755 : 142493 : if (op != smul_widen_optab)
2756 : : {
2757 : : /* We can use a signed multiply with unsigned types as long as
2758 : : there is a wider mode to use, or it is the smaller of the two
2759 : : types that is unsigned. Note that type1 >= type2, always. */
2760 : 89116 : if ((TYPE_UNSIGNED (type1)
2761 : 87419 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2762 : 89116 : || (TYPE_UNSIGNED (type2)
2763 : 1697 : && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
2764 : : {
2765 : 89116 : if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
2766 : 178232 : || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
2767 : 89116 : return false;
2768 : : }
2769 : :
2770 : 0 : op = smul_widen_optab;
2771 : 0 : handler = find_widening_optab_handler_and_mode (op, to_mode,
2772 : : from_mode,
2773 : : &actual_mode);
2774 : :
2775 : 0 : if (handler == CODE_FOR_nothing)
2776 : : return false;
2777 : :
2778 : : from_unsigned1 = from_unsigned2 = false;
2779 : : }
2780 : : else
2781 : : {
2782 : : /* Expand can synthesize smul_widen_optab if the target
2783 : : supports umul_widen_optab. */
2784 : 53377 : op = umul_widen_optab;
2785 : 53377 : handler = find_widening_optab_handler_and_mode (op, to_mode,
2786 : : from_mode,
2787 : : &actual_mode);
2788 : 53377 : if (handler == CODE_FOR_nothing)
2789 : : return false;
2790 : : }
2791 : : }
2792 : :
2793 : : /* Ensure that the inputs to the handler are in the correct precison
2794 : : for the opcode. This will be the full mode size. */
2795 : 10288 : actual_precision = GET_MODE_PRECISION (actual_mode);
2796 : 10288 : if (2 * actual_precision > TYPE_PRECISION (type))
2797 : : return false;
2798 : 10288 : if (actual_precision != TYPE_PRECISION (type1)
2799 : 10288 : || from_unsigned1 != TYPE_UNSIGNED (type1))
2800 : : {
2801 : 7 : if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
2802 : : {
2803 : 0 : if (TREE_CODE (rhs1) == INTEGER_CST)
2804 : 0 : rhs1 = fold_convert (type1, rhs1);
2805 : : else
2806 : 0 : rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
2807 : : }
2808 : 7 : type1 = build_nonstandard_integer_type (actual_precision,
2809 : : from_unsigned1);
2810 : : }
2811 : 10288 : if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
2812 : : {
2813 : 9567 : if (TREE_CODE (rhs1) == INTEGER_CST)
2814 : 0 : rhs1 = fold_convert (type1, rhs1);
2815 : : else
2816 : 9567 : rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
2817 : : }
2818 : 10288 : if (actual_precision != TYPE_PRECISION (type2)
2819 : 10288 : || from_unsigned2 != TYPE_UNSIGNED (type2))
2820 : : {
2821 : 7 : if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
2822 : : {
2823 : 7 : if (TREE_CODE (rhs2) == INTEGER_CST)
2824 : 7 : rhs2 = fold_convert (type2, rhs2);
2825 : : else
2826 : 0 : rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
2827 : : }
2828 : 7 : type2 = build_nonstandard_integer_type (actual_precision,
2829 : : from_unsigned2);
2830 : : }
2831 : 10288 : if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
2832 : : {
2833 : 9758 : if (TREE_CODE (rhs2) == INTEGER_CST)
2834 : 2254 : rhs2 = fold_convert (type2, rhs2);
2835 : : else
2836 : 7504 : rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
2837 : : }
2838 : :
2839 : 10288 : gimple_assign_set_rhs1 (stmt, rhs1);
2840 : 10288 : gimple_assign_set_rhs2 (stmt, rhs2);
2841 : 10288 : gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
2842 : 10288 : update_stmt (stmt);
2843 : 10288 : widen_mul_stats.widen_mults_inserted++;
2844 : 10288 : return true;
2845 : : }
2846 : :
2847 : : /* Process a single gimple statement STMT, which is found at the
2848 : : iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
2849 : : rhs (given by CODE), and try to convert it into a
2850 : : WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR. The return value
2851 : : is true iff we converted the statement. */
2852 : :
2853 : : static bool
2854 : 2541575 : convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
2855 : : enum tree_code code)
2856 : : {
2857 : 2541575 : gimple *rhs1_stmt = NULL, *rhs2_stmt = NULL;
2858 : 2541575 : gimple *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
2859 : 2541575 : tree type, type1, type2, optype;
2860 : 2541575 : tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
2861 : 2541575 : enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
2862 : 2541575 : optab this_optab;
2863 : 2541575 : enum tree_code wmult_code;
2864 : 2541575 : enum insn_code handler;
2865 : 2541575 : scalar_mode to_mode, from_mode, actual_mode;
2866 : 2541575 : location_t loc = gimple_location (stmt);
2867 : 2541575 : int actual_precision;
2868 : 2541575 : bool from_unsigned1, from_unsigned2;
2869 : :
2870 : 2541575 : lhs = gimple_assign_lhs (stmt);
2871 : 2541575 : type = TREE_TYPE (lhs);
2872 : 2541575 : if ((TREE_CODE (type) != INTEGER_TYPE
2873 : 395573 : && TREE_CODE (type) != FIXED_POINT_TYPE)
2874 : 2541575 : || !type_has_mode_precision_p (type))
2875 : 397249 : return false;
2876 : :
2877 : 2144326 : if (code == MINUS_EXPR)
2878 : : wmult_code = WIDEN_MULT_MINUS_EXPR;
2879 : : else
2880 : 1899605 : wmult_code = WIDEN_MULT_PLUS_EXPR;
2881 : :
2882 : 2144326 : rhs1 = gimple_assign_rhs1 (stmt);
2883 : 2144326 : rhs2 = gimple_assign_rhs2 (stmt);
2884 : :
2885 : 2144326 : if (TREE_CODE (rhs1) == SSA_NAME)
2886 : : {
2887 : 2108390 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2888 : 2108390 : if (is_gimple_assign (rhs1_stmt))
2889 : 1230794 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2890 : : }
2891 : :
2892 : 2144326 : if (TREE_CODE (rhs2) == SSA_NAME)
2893 : : {
2894 : 776654 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2895 : 776654 : if (is_gimple_assign (rhs2_stmt))
2896 : 592722 : rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
2897 : : }
2898 : :
2899 : : /* Allow for one conversion statement between the multiply
2900 : : and addition/subtraction statement. If there are more than
2901 : : one conversions then we assume they would invalidate this
2902 : : transformation. If that's not the case then they should have
2903 : : been folded before now. */
2904 : 2144326 : if (CONVERT_EXPR_CODE_P (rhs1_code))
2905 : : {
2906 : 416339 : conv1_stmt = rhs1_stmt;
2907 : 416339 : rhs1 = gimple_assign_rhs1 (rhs1_stmt);
2908 : 416339 : if (TREE_CODE (rhs1) == SSA_NAME)
2909 : : {
2910 : 350706 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2911 : 350706 : if (is_gimple_assign (rhs1_stmt))
2912 : 200683 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2913 : : }
2914 : : else
2915 : : return false;
2916 : : }
2917 : 2078693 : if (CONVERT_EXPR_CODE_P (rhs2_code))
2918 : : {
2919 : 187548 : conv2_stmt = rhs2_stmt;
2920 : 187548 : rhs2 = gimple_assign_rhs1 (rhs2_stmt);
2921 : 187548 : if (TREE_CODE (rhs2) == SSA_NAME)
2922 : : {
2923 : 174516 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2924 : 174516 : if (is_gimple_assign (rhs2_stmt))
2925 : 109879 : rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
2926 : : }
2927 : : else
2928 : : return false;
2929 : : }
2930 : :
2931 : : /* If code is WIDEN_MULT_EXPR then it would seem unnecessary to call
2932 : : is_widening_mult_p, but we still need the rhs returns.
2933 : :
2934 : : It might also appear that it would be sufficient to use the existing
2935 : : operands of the widening multiply, but that would limit the choice of
2936 : : multiply-and-accumulate instructions.
2937 : :
2938 : : If the widened-multiplication result has more than one uses, it is
2939 : : probably wiser not to do the conversion. Also restrict this operation
2940 : : to single basic block to avoid moving the multiply to a different block
2941 : : with a higher execution frequency. */
2942 : 2065661 : if (code == PLUS_EXPR
2943 : 1827090 : && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
2944 : : {
2945 : 127209 : if (!has_single_use (rhs1)
2946 : 72806 : || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
2947 : 192005 : || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
2948 : : &type2, &mult_rhs2))
2949 : 107134 : return false;
2950 : : add_rhs = rhs2;
2951 : : conv_stmt = conv1_stmt;
2952 : : }
2953 : 1938452 : else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
2954 : : {
2955 : 122014 : if (!has_single_use (rhs2)
2956 : 75090 : || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
2957 : 190098 : || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
2958 : : &type2, &mult_rhs2))
2959 : 107161 : return false;
2960 : : add_rhs = rhs1;
2961 : : conv_stmt = conv2_stmt;
2962 : : }
2963 : : else
2964 : : return false;
2965 : :
2966 : 34928 : to_mode = SCALAR_TYPE_MODE (type);
2967 : 34928 : from_mode = SCALAR_TYPE_MODE (type1);
2968 : 34928 : if (to_mode == from_mode)
2969 : : return false;
2970 : :
2971 : 34925 : from_unsigned1 = TYPE_UNSIGNED (type1);
2972 : 34925 : from_unsigned2 = TYPE_UNSIGNED (type2);
2973 : 34925 : optype = type1;
2974 : :
2975 : : /* There's no such thing as a mixed sign madd yet, so use a wider mode. */
2976 : 34925 : if (from_unsigned1 != from_unsigned2)
2977 : : {
2978 : 906 : if (!INTEGRAL_TYPE_P (type))
2979 : : return false;
2980 : : /* We can use a signed multiply with unsigned types as long as
2981 : : there is a wider mode to use, or it is the smaller of the two
2982 : : types that is unsigned. Note that type1 >= type2, always. */
2983 : 906 : if ((from_unsigned1
2984 : 56 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2985 : 906 : || (from_unsigned2
2986 : 850 : && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
2987 : : {
2988 : 1776 : if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
2989 : 1812 : || GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
2990 : 870 : return false;
2991 : : }
2992 : :
2993 : 36 : from_unsigned1 = from_unsigned2 = false;
2994 : 36 : optype = build_nonstandard_integer_type (GET_MODE_PRECISION (from_mode),
2995 : : false);
2996 : : }
2997 : :
2998 : : /* If there was a conversion between the multiply and addition
2999 : : then we need to make sure it fits a multiply-and-accumulate.
3000 : : The should be a single mode change which does not change the
3001 : : value. */
3002 : 34055 : if (conv_stmt)
3003 : : {
3004 : : /* We use the original, unmodified data types for this. */
3005 : 710 : tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
3006 : 710 : tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
3007 : 710 : int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
3008 : 710 : bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
3009 : :
3010 : 710 : if (TYPE_PRECISION (from_type) > TYPE_PRECISION (to_type))
3011 : : {
3012 : : /* Conversion is a truncate. */
3013 : 0 : if (TYPE_PRECISION (to_type) < data_size)
3014 : : return false;
3015 : : }
3016 : 710 : else if (TYPE_PRECISION (from_type) < TYPE_PRECISION (to_type))
3017 : : {
3018 : : /* Conversion is an extend. Check it's the right sort. */
3019 : 382 : if (TYPE_UNSIGNED (from_type) != is_unsigned
3020 : 382 : && !(is_unsigned && TYPE_PRECISION (from_type) > data_size))
3021 : : return false;
3022 : : }
3023 : : /* else convert is a no-op for our purposes. */
3024 : : }
3025 : :
3026 : : /* Verify that the machine can perform a widening multiply
3027 : : accumulate in this mode/signedness combination, otherwise
3028 : : this transformation is likely to pessimize code. */
3029 : 33736 : this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
3030 : 33736 : handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
3031 : : from_mode, &actual_mode);
3032 : :
3033 : 33736 : if (handler == CODE_FOR_nothing)
3034 : : return false;
3035 : :
3036 : : /* Ensure that the inputs to the handler are in the correct precison
3037 : : for the opcode. This will be the full mode size. */
3038 : 0 : actual_precision = GET_MODE_PRECISION (actual_mode);
3039 : 0 : if (actual_precision != TYPE_PRECISION (type1)
3040 : 0 : || from_unsigned1 != TYPE_UNSIGNED (type1))
3041 : : {
3042 : 0 : if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
3043 : : {
3044 : 0 : if (TREE_CODE (mult_rhs1) == INTEGER_CST)
3045 : 0 : mult_rhs1 = fold_convert (type1, mult_rhs1);
3046 : : else
3047 : 0 : mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
3048 : : }
3049 : 0 : type1 = build_nonstandard_integer_type (actual_precision,
3050 : : from_unsigned1);
3051 : : }
3052 : 0 : if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
3053 : : {
3054 : 0 : if (TREE_CODE (mult_rhs1) == INTEGER_CST)
3055 : 0 : mult_rhs1 = fold_convert (type1, mult_rhs1);
3056 : : else
3057 : 0 : mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
3058 : : }
3059 : 0 : if (actual_precision != TYPE_PRECISION (type2)
3060 : 0 : || from_unsigned2 != TYPE_UNSIGNED (type2))
3061 : : {
3062 : 0 : if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
3063 : : {
3064 : 0 : if (TREE_CODE (mult_rhs2) == INTEGER_CST)
3065 : 0 : mult_rhs2 = fold_convert (type2, mult_rhs2);
3066 : : else
3067 : 0 : mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
3068 : : }
3069 : 0 : type2 = build_nonstandard_integer_type (actual_precision,
3070 : : from_unsigned2);
3071 : : }
3072 : 0 : if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
3073 : : {
3074 : 0 : if (TREE_CODE (mult_rhs2) == INTEGER_CST)
3075 : 0 : mult_rhs2 = fold_convert (type2, mult_rhs2);
3076 : : else
3077 : 0 : mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
3078 : : }
3079 : :
3080 : 0 : if (!useless_type_conversion_p (type, TREE_TYPE (add_rhs)))
3081 : 0 : add_rhs = build_and_insert_cast (gsi, loc, type, add_rhs);
3082 : :
3083 : 0 : gimple_assign_set_rhs_with_ops (gsi, wmult_code, mult_rhs1, mult_rhs2,
3084 : : add_rhs);
3085 : 0 : update_stmt (gsi_stmt (*gsi));
3086 : 0 : widen_mul_stats.maccs_inserted++;
3087 : 0 : return true;
3088 : : }
3089 : :
3090 : : /* Given a result MUL_RESULT which is a result of a multiplication of OP1 and
3091 : : OP2 and which we know is used in statements that can be, together with the
3092 : : multiplication, converted to FMAs, perform the transformation. */
3093 : :
3094 : : static void
3095 : 17631 : convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
3096 : : {
3097 : 17631 : tree type = TREE_TYPE (mul_result);
3098 : 17631 : gimple *use_stmt;
3099 : 17631 : imm_use_iterator imm_iter;
3100 : 17631 : gcall *fma_stmt;
3101 : :
3102 : 35324 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result)
3103 : : {
3104 : 17693 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
3105 : 17693 : tree addop, mulop1 = op1, result = mul_result;
3106 : 17693 : bool negate_p = false;
3107 : 17693 : gimple_seq seq = NULL;
3108 : :
3109 : 17693 : if (is_gimple_debug (use_stmt))
3110 : 0 : continue;
3111 : :
3112 : 17693 : if (is_gimple_assign (use_stmt)
3113 : 17693 : && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
3114 : : {
3115 : 700 : result = gimple_assign_lhs (use_stmt);
3116 : 700 : use_operand_p use_p;
3117 : 700 : gimple *neguse_stmt;
3118 : 700 : single_imm_use (gimple_assign_lhs (use_stmt), &use_p, &neguse_stmt);
3119 : 700 : gsi_remove (&gsi, true);
3120 : 700 : release_defs (use_stmt);
3121 : :
3122 : 700 : use_stmt = neguse_stmt;
3123 : 700 : gsi = gsi_for_stmt (use_stmt);
3124 : 700 : negate_p = true;
3125 : : }
3126 : :
3127 : 17693 : tree cond, else_value, ops[3], len, bias;
3128 : 17693 : tree_code code;
3129 : 17693 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code,
3130 : : ops, &else_value,
3131 : : &len, &bias))
3132 : 0 : gcc_unreachable ();
3133 : 17693 : addop = ops[0] == result ? ops[1] : ops[0];
3134 : :
3135 : 17693 : if (code == MINUS_EXPR)
3136 : : {
3137 : 5723 : if (ops[0] == result)
3138 : : /* a * b - c -> a * b + (-c) */
3139 : 2902 : addop = gimple_build (&seq, NEGATE_EXPR, type, addop);
3140 : : else
3141 : : /* a - b * c -> (-b) * c + a */
3142 : 2821 : negate_p = !negate_p;
3143 : : }
3144 : :
3145 : 17693 : if (negate_p)
3146 : 3521 : mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1);
3147 : :
3148 : 17693 : if (seq)
3149 : 5718 : gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
3150 : :
3151 : 17693 : if (len)
3152 : 0 : fma_stmt
3153 : 0 : = gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2,
3154 : : addop, else_value, len, bias);
3155 : 17693 : else if (cond)
3156 : 94 : fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
3157 : : op2, addop, else_value);
3158 : : else
3159 : 17599 : fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
3160 : 17693 : gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
3161 : 17693 : gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
3162 : : use_stmt));
3163 : 17693 : gsi_replace (&gsi, fma_stmt, true);
3164 : : /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
3165 : : regardless of where the negation occurs. */
3166 : 17693 : gimple *orig_stmt = gsi_stmt (gsi);
3167 : 17693 : if (fold_stmt (&gsi, follow_all_ssa_edges))
3168 : : {
3169 : 5767 : if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
3170 : 0 : gcc_unreachable ();
3171 : 5767 : update_stmt (gsi_stmt (gsi));
3172 : : }
3173 : :
3174 : 17693 : if (dump_file && (dump_flags & TDF_DETAILS))
3175 : : {
3176 : 3 : fprintf (dump_file, "Generated FMA ");
3177 : 3 : print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
3178 : 3 : fprintf (dump_file, "\n");
3179 : : }
3180 : :
3181 : : /* If the FMA result is negated in a single use, fold the negation
3182 : : too. */
3183 : 17693 : orig_stmt = gsi_stmt (gsi);
3184 : 17693 : use_operand_p use_p;
3185 : 17693 : gimple *neg_stmt;
3186 : 17693 : if (is_gimple_call (orig_stmt)
3187 : 17693 : && gimple_call_internal_p (orig_stmt)
3188 : 17693 : && gimple_call_lhs (orig_stmt)
3189 : 17693 : && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME
3190 : 17693 : && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt)
3191 : 11288 : && is_gimple_assign (neg_stmt)
3192 : 8596 : && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR
3193 : 19046 : && !stmt_could_throw_p (cfun, neg_stmt))
3194 : : {
3195 : 1353 : gsi = gsi_for_stmt (neg_stmt);
3196 : 1353 : if (fold_stmt (&gsi, follow_all_ssa_edges))
3197 : : {
3198 : 1353 : if (maybe_clean_or_replace_eh_stmt (neg_stmt, gsi_stmt (gsi)))
3199 : 0 : gcc_unreachable ();
3200 : 1353 : update_stmt (gsi_stmt (gsi));
3201 : 1353 : if (dump_file && (dump_flags & TDF_DETAILS))
3202 : : {
3203 : 0 : fprintf (dump_file, "Folded FMA negation ");
3204 : 0 : print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
3205 : 0 : fprintf (dump_file, "\n");
3206 : : }
3207 : : }
3208 : : }
3209 : :
3210 : 17693 : widen_mul_stats.fmas_inserted++;
3211 : 17631 : }
3212 : 17631 : }
3213 : :
3214 : : /* Data necessary to perform the actual transformation from a multiplication
3215 : : and an addition to an FMA after decision is taken it should be done and to
3216 : : then delete the multiplication statement from the function IL. */
3217 : :
3218 : : struct fma_transformation_info
3219 : : {
3220 : : gimple *mul_stmt;
3221 : : tree mul_result;
3222 : : tree op1;
3223 : : tree op2;
3224 : : };
3225 : :
3226 : : /* Structure containing the current state of FMA deferring, i.e. whether we are
3227 : : deferring, whether to continue deferring, and all data necessary to come
3228 : : back and perform all deferred transformations. */
3229 : :
3230 : 10584994 : class fma_deferring_state
3231 : : {
3232 : : public:
3233 : : /* Class constructor. Pass true as PERFORM_DEFERRING in order to actually
3234 : : do any deferring. */
3235 : :
3236 : 10584994 : fma_deferring_state (bool perform_deferring)
3237 : 10584994 : : m_candidates (), m_mul_result_set (), m_initial_phi (NULL),
3238 : 10584994 : m_last_result (NULL_TREE), m_deferring_p (perform_deferring) {}
3239 : :
3240 : : /* List of FMA candidates for which we the transformation has been determined
3241 : : possible but we at this point in BB analysis we do not consider them
3242 : : beneficial. */
3243 : : auto_vec<fma_transformation_info, 8> m_candidates;
3244 : :
3245 : : /* Set of results of multiplication that are part of an already deferred FMA
3246 : : candidates. */
3247 : : hash_set<tree> m_mul_result_set;
3248 : :
3249 : : /* The PHI that supposedly feeds back result of a FMA to another over loop
3250 : : boundary. */
3251 : : gphi *m_initial_phi;
3252 : :
3253 : : /* Result of the last produced FMA candidate or NULL if there has not been
3254 : : one. */
3255 : : tree m_last_result;
3256 : :
3257 : : /* If true, deferring might still be profitable. If false, transform all
3258 : : candidates and no longer defer. */
3259 : : bool m_deferring_p;
3260 : : };
3261 : :
3262 : : /* Transform all deferred FMA candidates and mark STATE as no longer
3263 : : deferring. */
3264 : :
3265 : : static void
3266 : 3632839 : cancel_fma_deferring (fma_deferring_state *state)
3267 : : {
3268 : 3632839 : if (!state->m_deferring_p)
3269 : : return;
3270 : :
3271 : 2651472 : for (unsigned i = 0; i < state->m_candidates.length (); i++)
3272 : : {
3273 : 907 : if (dump_file && (dump_flags & TDF_DETAILS))
3274 : 0 : fprintf (dump_file, "Generating deferred FMA\n");
3275 : :
3276 : 907 : const fma_transformation_info &fti = state->m_candidates[i];
3277 : 907 : convert_mult_to_fma_1 (fti.mul_result, fti.op1, fti.op2);
3278 : :
3279 : 907 : gimple_stmt_iterator gsi = gsi_for_stmt (fti.mul_stmt);
3280 : 907 : gsi_remove (&gsi, true);
3281 : 907 : release_defs (fti.mul_stmt);
3282 : : }
3283 : 2650565 : state->m_deferring_p = false;
3284 : : }
3285 : :
3286 : : /* If OP is an SSA name defined by a PHI node, return the PHI statement.
3287 : : Otherwise return NULL. */
3288 : :
3289 : : static gphi *
3290 : 5155 : result_of_phi (tree op)
3291 : : {
3292 : 0 : if (TREE_CODE (op) != SSA_NAME)
3293 : : return NULL;
3294 : :
3295 : 5110 : return dyn_cast <gphi *> (SSA_NAME_DEF_STMT (op));
3296 : : }
3297 : :
3298 : : /* After processing statements of a BB and recording STATE, return true if the
3299 : : initial phi is fed by the last FMA candidate result ore one such result from
3300 : : previously processed BBs marked in LAST_RESULT_SET. */
3301 : :
3302 : : static bool
3303 : 361 : last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
3304 : : hash_set<tree> *last_result_set)
3305 : : {
3306 : 361 : ssa_op_iter iter;
3307 : 361 : use_operand_p use;
3308 : 897 : FOR_EACH_PHI_ARG (use, state->m_initial_phi, iter, SSA_OP_USE)
3309 : : {
3310 : 629 : tree t = USE_FROM_PTR (use);
3311 : 629 : if (t == state->m_last_result
3312 : 629 : || last_result_set->contains (t))
3313 : 93 : return true;
3314 : : }
3315 : :
3316 : : return false;
3317 : : }
3318 : :
3319 : : /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
3320 : : with uses in additions and subtractions to form fused multiply-add
3321 : : operations. Returns true if successful and MUL_STMT should be removed.
3322 : : If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
3323 : : on MUL_COND, otherwise it is unconditional.
3324 : :
3325 : : If STATE indicates that we are deferring FMA transformation, that means
3326 : : that we do not produce FMAs for basic blocks which look like:
3327 : :
3328 : : <bb 6>
3329 : : # accumulator_111 = PHI <0.0(5), accumulator_66(6)>
3330 : : _65 = _14 * _16;
3331 : : accumulator_66 = _65 + accumulator_111;
3332 : :
3333 : : or its unrolled version, i.e. with several FMA candidates that feed result
3334 : : of one into the addend of another. Instead, we add them to a list in STATE
3335 : : and if we later discover an FMA candidate that is not part of such a chain,
3336 : : we go back and perform all deferred past candidates. */
3337 : :
3338 : : static bool
3339 : 699603 : convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
3340 : : fma_deferring_state *state, tree mul_cond = NULL_TREE,
3341 : : tree mul_len = NULL_TREE, tree mul_bias = NULL_TREE)
3342 : : {
3343 : 699603 : tree mul_result = gimple_get_lhs (mul_stmt);
3344 : : /* If there isn't a LHS then this can't be an FMA. There can be no LHS
3345 : : if the statement was left just for the side-effects. */
3346 : 699603 : if (!mul_result)
3347 : : return false;
3348 : 699603 : tree type = TREE_TYPE (mul_result);
3349 : 699603 : gimple *use_stmt, *neguse_stmt;
3350 : 699603 : use_operand_p use_p;
3351 : 699603 : imm_use_iterator imm_iter;
3352 : :
3353 : 602767 : if (FLOAT_TYPE_P (type)
3354 : 723719 : && flag_fp_contract_mode != FP_CONTRACT_FAST)
3355 : : return false;
3356 : :
3357 : : /* We don't want to do bitfield reduction ops. */
3358 : 694463 : if (INTEGRAL_TYPE_P (type)
3359 : 694463 : && (!type_has_mode_precision_p (type) || TYPE_OVERFLOW_TRAPS (type)))
3360 : : return false;
3361 : :
3362 : : /* If the target doesn't support it, don't generate it. We assume that
3363 : : if fma isn't available then fms, fnma or fnms are not either. */
3364 : 694293 : optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt));
3365 : 694293 : if (!direct_internal_fn_supported_p (IFN_FMA, type, opt_type))
3366 : : return false;
3367 : :
3368 : : /* If the multiplication has zero uses, it is kept around probably because
3369 : : of -fnon-call-exceptions. Don't optimize it away in that case,
3370 : : it is DCE job. */
3371 : 22625 : if (has_zero_uses (mul_result))
3372 : : return false;
3373 : :
3374 : 22625 : bool check_defer
3375 : 22625 : = (state->m_deferring_p
3376 : 22625 : && maybe_le (tree_to_poly_int64 (TYPE_SIZE (type)),
3377 : 22625 : param_avoid_fma_max_bits));
3378 : 22625 : bool defer = check_defer;
3379 : 22625 : bool seen_negate_p = false;
3380 : :
3381 : : /* There is no numerical difference between fused and unfused integer FMAs,
3382 : : and the assumption below that FMA is as cheap as addition is unlikely
3383 : : to be true, especially if the multiplication occurs multiple times on
3384 : : the same chain. E.g., for something like:
3385 : :
3386 : : (((a * b) + c) >> 1) + (a * b)
3387 : :
3388 : : we do not want to duplicate the a * b into two additions, not least
3389 : : because the result is not a natural FMA chain. */
3390 : 22625 : if (ANY_INTEGRAL_TYPE_P (type)
3391 : 22625 : && !has_single_use (mul_result))
3392 : : return false;
3393 : :
3394 : 22625 : if (!dbg_cnt (form_fma))
3395 : : return false;
3396 : :
3397 : : /* Make sure that the multiplication statement becomes dead after
3398 : : the transformation, thus that all uses are transformed to FMAs.
3399 : : This means we assume that an FMA operation has the same cost
3400 : : as an addition. */
3401 : 41155 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
3402 : : {
3403 : 23431 : tree result = mul_result;
3404 : 23431 : bool negate_p = false;
3405 : :
3406 : 23431 : use_stmt = USE_STMT (use_p);
3407 : :
3408 : 23431 : if (is_gimple_debug (use_stmt))
3409 : 286 : continue;
3410 : :
3411 : : /* For now restrict this operations to single basic blocks. In theory
3412 : : we would want to support sinking the multiplication in
3413 : : m = a*b;
3414 : : if ()
3415 : : ma = m + c;
3416 : : else
3417 : : d = m;
3418 : : to form a fma in the then block and sink the multiplication to the
3419 : : else block. */
3420 : 23145 : if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3421 : 4901 : return false;
3422 : :
3423 : : /* A negate on the multiplication leads to FNMA. */
3424 : 22297 : if (is_gimple_assign (use_stmt)
3425 : 22297 : && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
3426 : : {
3427 : 706 : ssa_op_iter iter;
3428 : 706 : use_operand_p usep;
3429 : :
3430 : : /* If (due to earlier missed optimizations) we have two
3431 : : negates of the same value, treat them as equivalent
3432 : : to a single negate with multiple uses. */
3433 : 706 : if (seen_negate_p)
3434 : 0 : return false;
3435 : :
3436 : 706 : result = gimple_assign_lhs (use_stmt);
3437 : :
3438 : : /* Make sure the negate statement becomes dead with this
3439 : : single transformation. */
3440 : 706 : if (!single_imm_use (gimple_assign_lhs (use_stmt),
3441 : : &use_p, &neguse_stmt))
3442 : : return false;
3443 : :
3444 : : /* Make sure the multiplication isn't also used on that stmt. */
3445 : 2836 : FOR_EACH_PHI_OR_STMT_USE (usep, neguse_stmt, iter, SSA_OP_USE)
3446 : 1424 : if (USE_FROM_PTR (usep) == mul_result)
3447 : : return false;
3448 : :
3449 : : /* Re-validate. */
3450 : 706 : use_stmt = neguse_stmt;
3451 : 706 : if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3452 : : return false;
3453 : :
3454 : 706 : negate_p = seen_negate_p = true;
3455 : : }
3456 : :
3457 : 22297 : tree cond, else_value, ops[3], len, bias;
3458 : 22297 : tree_code code;
3459 : 22297 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
3460 : : &else_value, &len, &bias))
3461 : : return false;
3462 : :
3463 : 20082 : switch (code)
3464 : : {
3465 : 5729 : case MINUS_EXPR:
3466 : 5729 : if (ops[1] == result)
3467 : 2821 : negate_p = !negate_p;
3468 : : break;
3469 : : case PLUS_EXPR:
3470 : : break;
3471 : : default:
3472 : : /* FMA can only be formed from PLUS and MINUS. */
3473 : : return false;
3474 : : }
3475 : :
3476 : 18266 : if (len)
3477 : : {
3478 : : /* For COND_LEN_* operations, we may have dummpy mask which is
3479 : : the all true mask. Such TREE type may be mul_cond != cond
3480 : : but we still consider they are equal. */
3481 : 0 : if (mul_cond && cond != mul_cond
3482 : 0 : && !(integer_truep (mul_cond) && integer_truep (cond)))
3483 : 0 : return false;
3484 : :
3485 : 0 : if (else_value == result)
3486 : : return false;
3487 : :
3488 : 0 : if (!direct_internal_fn_supported_p (IFN_COND_LEN_FMA, type,
3489 : : opt_type))
3490 : : return false;
3491 : :
3492 : 0 : if (mul_len)
3493 : : {
3494 : 0 : poly_int64 mul_value, value;
3495 : 0 : if (poly_int_tree_p (mul_len, &mul_value)
3496 : 0 : && poly_int_tree_p (len, &value)
3497 : 0 : && maybe_ne (mul_value, value))
3498 : 0 : return false;
3499 : 0 : else if (mul_len != len)
3500 : : return false;
3501 : :
3502 : 0 : if (wi::to_widest (mul_bias) != wi::to_widest (bias))
3503 : : return false;
3504 : : }
3505 : : }
3506 : : else
3507 : : {
3508 : 18266 : if (mul_cond && cond != mul_cond)
3509 : : return false;
3510 : :
3511 : 18254 : if (cond)
3512 : : {
3513 : 104 : if (cond == result || else_value == result)
3514 : : return false;
3515 : 94 : if (!direct_internal_fn_supported_p (IFN_COND_FMA, type,
3516 : : opt_type))
3517 : : return false;
3518 : : }
3519 : : }
3520 : :
3521 : : /* If the subtrahend (OPS[1]) is computed by a MULT_EXPR that
3522 : : we'll visit later, we might be able to get a more profitable
3523 : : match with fnma.
3524 : : OTOH, if we don't, a negate / fma pair has likely lower latency
3525 : : that a mult / subtract pair. */
3526 : 18244 : if (code == MINUS_EXPR
3527 : 5723 : && !negate_p
3528 : 2202 : && ops[0] == result
3529 : 2202 : && !direct_internal_fn_supported_p (IFN_FMS, type, opt_type)
3530 : 0 : && direct_internal_fn_supported_p (IFN_FNMA, type, opt_type)
3531 : 0 : && TREE_CODE (ops[1]) == SSA_NAME
3532 : 18244 : && has_single_use (ops[1]))
3533 : : {
3534 : 0 : gimple *stmt2 = SSA_NAME_DEF_STMT (ops[1]);
3535 : 0 : if (is_gimple_assign (stmt2)
3536 : 0 : && gimple_assign_rhs_code (stmt2) == MULT_EXPR)
3537 : : return false;
3538 : : }
3539 : :
3540 : : /* We can't handle a * b + a * b. */
3541 : 18244 : if (ops[0] == ops[1])
3542 : : return false;
3543 : : /* If deferring, make sure we are not looking at an instruction that
3544 : : wouldn't have existed if we were not. */
3545 : 18244 : if (state->m_deferring_p
3546 : 18244 : && (state->m_mul_result_set.contains (ops[0])
3547 : 6310 : || state->m_mul_result_set.contains (ops[1])))
3548 : 0 : return false;
3549 : :
3550 : 18244 : if (check_defer)
3551 : : {
3552 : 6162 : tree use_lhs = gimple_get_lhs (use_stmt);
3553 : 6162 : if (state->m_last_result)
3554 : : {
3555 : 1007 : if (ops[1] == state->m_last_result
3556 : 1007 : || ops[0] == state->m_last_result)
3557 : : defer = true;
3558 : : else
3559 : 6162 : defer = false;
3560 : : }
3561 : : else
3562 : : {
3563 : 5155 : gcc_checking_assert (!state->m_initial_phi);
3564 : 5155 : gphi *phi;
3565 : 5155 : if (ops[0] == result)
3566 : 3153 : phi = result_of_phi (ops[1]);
3567 : : else
3568 : : {
3569 : 2002 : gcc_assert (ops[1] == result);
3570 : 2002 : phi = result_of_phi (ops[0]);
3571 : : }
3572 : :
3573 : : if (phi)
3574 : : {
3575 : 928 : state->m_initial_phi = phi;
3576 : 928 : defer = true;
3577 : : }
3578 : : else
3579 : : defer = false;
3580 : : }
3581 : :
3582 : 6162 : state->m_last_result = use_lhs;
3583 : 6162 : check_defer = false;
3584 : : }
3585 : : else
3586 : : defer = false;
3587 : :
3588 : : /* While it is possible to validate whether or not the exact form that
3589 : : we've recognized is available in the backend, the assumption is that
3590 : : if the deferring logic above did not trigger, the transformation is
3591 : : never a loss. For instance, suppose the target only has the plain FMA
3592 : : pattern available. Consider a*b-c -> fma(a,b,-c): we've exchanged
3593 : : MUL+SUB for FMA+NEG, which is still two operations. Consider
3594 : : -(a*b)-c -> fma(-a,b,-c): we still have 3 operations, but in the FMA
3595 : : form the two NEGs are independent and could be run in parallel. */
3596 : : }
3597 : :
3598 : 17724 : if (defer)
3599 : : {
3600 : 1000 : fma_transformation_info fti;
3601 : 1000 : fti.mul_stmt = mul_stmt;
3602 : 1000 : fti.mul_result = mul_result;
3603 : 1000 : fti.op1 = op1;
3604 : 1000 : fti.op2 = op2;
3605 : 1000 : state->m_candidates.safe_push (fti);
3606 : 1000 : state->m_mul_result_set.add (mul_result);
3607 : :
3608 : 1000 : if (dump_file && (dump_flags & TDF_DETAILS))
3609 : : {
3610 : 0 : fprintf (dump_file, "Deferred generating FMA for multiplication ");
3611 : 0 : print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE);
3612 : 0 : fprintf (dump_file, "\n");
3613 : : }
3614 : :
3615 : 1000 : return false;
3616 : : }
3617 : : else
3618 : : {
3619 : 16724 : if (state->m_deferring_p)
3620 : 4826 : cancel_fma_deferring (state);
3621 : 16724 : convert_mult_to_fma_1 (mul_result, op1, op2);
3622 : 16724 : return true;
3623 : : }
3624 : : }
3625 : :
3626 : :
3627 : : /* Helper function of match_arith_overflow. For MUL_OVERFLOW, if we have
3628 : : a check for non-zero like:
3629 : : _1 = x_4(D) * y_5(D);
3630 : : *res_7(D) = _1;
3631 : : if (x_4(D) != 0)
3632 : : goto <bb 3>; [50.00%]
3633 : : else
3634 : : goto <bb 4>; [50.00%]
3635 : :
3636 : : <bb 3> [local count: 536870913]:
3637 : : _2 = _1 / x_4(D);
3638 : : _9 = _2 != y_5(D);
3639 : : _10 = (int) _9;
3640 : :
3641 : : <bb 4> [local count: 1073741824]:
3642 : : # iftmp.0_3 = PHI <_10(3), 0(2)>
3643 : : then in addition to using .MUL_OVERFLOW (x_4(D), y_5(D)) we can also
3644 : : optimize the x_4(D) != 0 condition to 1. */
3645 : :
3646 : : static void
3647 : 145 : maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
3648 : : gimple *div_stmt, bool *cfg_changed)
3649 : : {
3650 : 145 : basic_block bb = gimple_bb (cond_stmt);
3651 : 290 : if (gimple_bb (div_stmt) != bb || !single_pred_p (bb))
3652 : 51 : return;
3653 : 145 : edge pred_edge = single_pred_edge (bb);
3654 : 145 : basic_block pred_bb = pred_edge->src;
3655 : 145 : if (EDGE_COUNT (pred_bb->succs) != 2)
3656 : : return;
3657 : 102 : edge other_edge = EDGE_SUCC (pred_bb, EDGE_SUCC (pred_bb, 0) == pred_edge);
3658 : 102 : edge other_succ_edge = NULL;
3659 : 102 : if (gimple_code (cond_stmt) == GIMPLE_COND)
3660 : : {
3661 : 48 : if (EDGE_COUNT (bb->succs) != 2)
3662 : : return;
3663 : 48 : other_succ_edge = EDGE_SUCC (bb, 0);
3664 : 48 : if (gimple_cond_code (cond_stmt) == NE_EXPR)
3665 : : {
3666 : 24 : if (other_succ_edge->flags & EDGE_TRUE_VALUE)
3667 : 24 : other_succ_edge = EDGE_SUCC (bb, 1);
3668 : : }
3669 : : else if (other_succ_edge->flags & EDGE_FALSE_VALUE)
3670 : 48 : other_succ_edge = EDGE_SUCC (bb, 0);
3671 : 48 : if (other_edge->dest != other_succ_edge->dest)
3672 : : return;
3673 : : }
3674 : 105 : else if (!single_succ_p (bb) || other_edge->dest != single_succ (bb))
3675 : : return;
3676 : 202 : gcond *zero_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (pred_bb));
3677 : 101 : if (zero_cond == NULL
3678 : 101 : || (gimple_cond_code (zero_cond)
3679 : 101 : != ((pred_edge->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR))
3680 : 101 : || !integer_zerop (gimple_cond_rhs (zero_cond)))
3681 : 0 : return;
3682 : 101 : tree zero_cond_lhs = gimple_cond_lhs (zero_cond);
3683 : 101 : if (TREE_CODE (zero_cond_lhs) != SSA_NAME)
3684 : : return;
3685 : 101 : if (gimple_assign_rhs2 (div_stmt) != zero_cond_lhs)
3686 : : {
3687 : : /* Allow the divisor to be result of a same precision cast
3688 : : from zero_cond_lhs. */
3689 : 53 : tree rhs2 = gimple_assign_rhs2 (div_stmt);
3690 : 53 : if (TREE_CODE (rhs2) != SSA_NAME)
3691 : : return;
3692 : 53 : gimple *g = SSA_NAME_DEF_STMT (rhs2);
3693 : 53 : if (!gimple_assign_cast_p (g)
3694 : 53 : || gimple_assign_rhs1 (g) != gimple_cond_lhs (zero_cond)
3695 : 53 : || !INTEGRAL_TYPE_P (TREE_TYPE (zero_cond_lhs))
3696 : 106 : || (TYPE_PRECISION (TREE_TYPE (zero_cond_lhs))
3697 : 53 : != TYPE_PRECISION (TREE_TYPE (rhs2))))
3698 : : return;
3699 : : }
3700 : 101 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
3701 : 101 : mul_stmts.quick_push (div_stmt);
3702 : 101 : if (is_gimple_debug (gsi_stmt (gsi)))
3703 : 0 : gsi_next_nondebug (&gsi);
3704 : : unsigned cast_count = 0;
3705 : 635 : while (gsi_stmt (gsi) != cond_stmt)
3706 : : {
3707 : : /* If original mul_stmt has a single use, allow it in the same bb,
3708 : : we are looking then just at __builtin_mul_overflow_p.
3709 : : Though, in that case the original mul_stmt will be replaced
3710 : : by .MUL_OVERFLOW, REALPART_EXPR and IMAGPART_EXPR stmts. */
3711 : : gimple *mul_stmt;
3712 : : unsigned int i;
3713 : 2274 : bool ok = false;
3714 : 2274 : FOR_EACH_VEC_ELT (mul_stmts, i, mul_stmt)
3715 : : {
3716 : 2127 : if (gsi_stmt (gsi) == mul_stmt)
3717 : : {
3718 : : ok = true;
3719 : : break;
3720 : : }
3721 : : }
3722 : 534 : if (!ok && gimple_assign_cast_p (gsi_stmt (gsi)) && ++cast_count < 4)
3723 : : ok = true;
3724 : 387 : if (!ok)
3725 : 51 : return;
3726 : 534 : gsi_next_nondebug (&gsi);
3727 : : }
3728 : 101 : if (gimple_code (cond_stmt) == GIMPLE_COND)
3729 : : {
3730 : 47 : basic_block succ_bb = other_edge->dest;
3731 : 75 : for (gphi_iterator gpi = gsi_start_phis (succ_bb); !gsi_end_p (gpi);
3732 : 28 : gsi_next (&gpi))
3733 : : {
3734 : 35 : gphi *phi = gpi.phi ();
3735 : 35 : tree v1 = gimple_phi_arg_def (phi, other_edge->dest_idx);
3736 : 35 : tree v2 = gimple_phi_arg_def (phi, other_succ_edge->dest_idx);
3737 : 35 : if (!operand_equal_p (v1, v2, 0))
3738 : 7 : return;
3739 : : }
3740 : : }
3741 : : else
3742 : : {
3743 : 54 : tree lhs = gimple_assign_lhs (cond_stmt);
3744 : 54 : if (!lhs || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
3745 : : return;
3746 : 54 : gsi_next_nondebug (&gsi);
3747 : 54 : if (!gsi_end_p (gsi))
3748 : : {
3749 : 54 : if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
3750 : : return;
3751 : 54 : gimple *cast_stmt = gsi_stmt (gsi);
3752 : 54 : if (!gimple_assign_cast_p (cast_stmt))
3753 : : return;
3754 : 54 : tree new_lhs = gimple_assign_lhs (cast_stmt);
3755 : 54 : gsi_next_nondebug (&gsi);
3756 : 54 : if (!gsi_end_p (gsi)
3757 : 54 : || !new_lhs
3758 : 54 : || !INTEGRAL_TYPE_P (TREE_TYPE (new_lhs))
3759 : 108 : || TYPE_PRECISION (TREE_TYPE (new_lhs)) <= 1)
3760 : : return;
3761 : : lhs = new_lhs;
3762 : : }
3763 : 54 : edge succ_edge = single_succ_edge (bb);
3764 : 54 : basic_block succ_bb = succ_edge->dest;
3765 : 54 : gsi = gsi_start_phis (succ_bb);
3766 : 54 : if (gsi_end_p (gsi))
3767 : : return;
3768 : 54 : gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
3769 : 54 : gsi_next (&gsi);
3770 : 54 : if (!gsi_end_p (gsi))
3771 : : return;
3772 : 54 : if (gimple_phi_arg_def (phi, succ_edge->dest_idx) != lhs)
3773 : : return;
3774 : 54 : tree other_val = gimple_phi_arg_def (phi, other_edge->dest_idx);
3775 : 54 : if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
3776 : : {
3777 : 0 : tree cond = gimple_assign_rhs1 (cond_stmt);
3778 : 0 : if (TREE_CODE (cond) == NE_EXPR)
3779 : : {
3780 : 0 : if (!operand_equal_p (other_val,
3781 : 0 : gimple_assign_rhs3 (cond_stmt), 0))
3782 : : return;
3783 : : }
3784 : 0 : else if (!operand_equal_p (other_val,
3785 : 0 : gimple_assign_rhs2 (cond_stmt), 0))
3786 : : return;
3787 : : }
3788 : 54 : else if (gimple_assign_rhs_code (cond_stmt) == NE_EXPR)
3789 : : {
3790 : 25 : if (!integer_zerop (other_val))
3791 : : return;
3792 : : }
3793 : 29 : else if (!integer_onep (other_val))
3794 : : return;
3795 : : }
3796 : 94 : if (pred_edge->flags & EDGE_TRUE_VALUE)
3797 : 41 : gimple_cond_make_true (zero_cond);
3798 : : else
3799 : 53 : gimple_cond_make_false (zero_cond);
3800 : 94 : update_stmt (zero_cond);
3801 : 94 : reset_flow_sensitive_info_in_bb (bb);
3802 : 94 : *cfg_changed = true;
3803 : : }
3804 : :
3805 : : /* Helper function for arith_overflow_check_p. Return true
3806 : : if VAL1 is equal to VAL2 cast to corresponding integral type
3807 : : with other signedness or vice versa. */
3808 : :
3809 : : static bool
3810 : 382 : arith_cast_equal_p (tree val1, tree val2)
3811 : : {
3812 : 382 : if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
3813 : 65 : return wi::eq_p (wi::to_wide (val1), wi::to_wide (val2));
3814 : 317 : else if (TREE_CODE (val1) != SSA_NAME || TREE_CODE (val2) != SSA_NAME)
3815 : : return false;
3816 : 280 : if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val1))
3817 : 280 : && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val1)) == val2)
3818 : : return true;
3819 : 168 : if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val2))
3820 : 168 : && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val2)) == val1)
3821 : 120 : return true;
3822 : : return false;
3823 : : }
3824 : :
3825 : : /* Helper function of match_arith_overflow. Return 1
3826 : : if USE_STMT is unsigned overflow check ovf != 0 for
3827 : : STMT, -1 if USE_STMT is unsigned overflow check ovf == 0
3828 : : and 0 otherwise. */
3829 : :
3830 : : static int
3831 : 2857777 : arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
3832 : : tree maxval, tree *other)
3833 : : {
3834 : 2857777 : enum tree_code ccode = ERROR_MARK;
3835 : 2857777 : tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
3836 : 2857777 : enum tree_code code = gimple_assign_rhs_code (stmt);
3837 : 5681332 : tree lhs = gimple_assign_lhs (cast_stmt ? cast_stmt : stmt);
3838 : 2857777 : tree rhs1 = gimple_assign_rhs1 (stmt);
3839 : 2857777 : tree rhs2 = gimple_assign_rhs2 (stmt);
3840 : 2857777 : tree multop = NULL_TREE, divlhs = NULL_TREE;
3841 : 2857777 : gimple *cur_use_stmt = use_stmt;
3842 : :
3843 : 2857777 : if (code == MULT_EXPR)
3844 : : {
3845 : 640140 : if (!is_gimple_assign (use_stmt))
3846 : 639844 : return 0;
3847 : 514822 : if (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR)
3848 : : return 0;
3849 : 2599 : if (gimple_assign_rhs1 (use_stmt) != lhs)
3850 : : return 0;
3851 : 2536 : if (cast_stmt)
3852 : : {
3853 : 155 : if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs1))
3854 : : multop = rhs2;
3855 : 81 : else if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs2))
3856 : : multop = rhs1;
3857 : : else
3858 : : return 0;
3859 : : }
3860 : 2381 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
3861 : : multop = rhs2;
3862 : 2303 : else if (operand_equal_p (gimple_assign_rhs2 (use_stmt), rhs2, 0))
3863 : : multop = rhs1;
3864 : : else
3865 : : return 0;
3866 : 300 : if (stmt_ends_bb_p (use_stmt))
3867 : : return 0;
3868 : 300 : divlhs = gimple_assign_lhs (use_stmt);
3869 : 300 : if (!divlhs)
3870 : : return 0;
3871 : 300 : use_operand_p use;
3872 : 300 : if (!single_imm_use (divlhs, &use, &cur_use_stmt))
3873 : : return 0;
3874 : 296 : if (cast_stmt && gimple_assign_cast_p (cur_use_stmt))
3875 : : {
3876 : 4 : tree cast_lhs = gimple_assign_lhs (cur_use_stmt);
3877 : 8 : if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
3878 : 4 : && TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
3879 : 4 : && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
3880 : 4 : == TYPE_PRECISION (TREE_TYPE (divlhs)))
3881 : 8 : && single_imm_use (cast_lhs, &use, &cur_use_stmt))
3882 : : {
3883 : : cast_stmt = NULL;
3884 : : divlhs = cast_lhs;
3885 : : }
3886 : : else
3887 : 0 : return 0;
3888 : : }
3889 : : }
3890 : 2217933 : if (gimple_code (cur_use_stmt) == GIMPLE_COND)
3891 : : {
3892 : 575201 : ccode = gimple_cond_code (cur_use_stmt);
3893 : 575201 : crhs1 = gimple_cond_lhs (cur_use_stmt);
3894 : 575201 : crhs2 = gimple_cond_rhs (cur_use_stmt);
3895 : : }
3896 : 1642732 : else if (is_gimple_assign (cur_use_stmt))
3897 : : {
3898 : 801298 : if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
3899 : : {
3900 : 476445 : ccode = gimple_assign_rhs_code (cur_use_stmt);
3901 : 476445 : crhs1 = gimple_assign_rhs1 (cur_use_stmt);
3902 : 476445 : crhs2 = gimple_assign_rhs2 (cur_use_stmt);
3903 : : }
3904 : 324853 : else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
3905 : : {
3906 : 5019 : tree cond = gimple_assign_rhs1 (cur_use_stmt);
3907 : 5019 : if (COMPARISON_CLASS_P (cond))
3908 : : {
3909 : 0 : ccode = TREE_CODE (cond);
3910 : 0 : crhs1 = TREE_OPERAND (cond, 0);
3911 : 0 : crhs2 = TREE_OPERAND (cond, 1);
3912 : : }
3913 : : else
3914 : : return 0;
3915 : : }
3916 : : else
3917 : : return 0;
3918 : : }
3919 : : else
3920 : : return 0;
3921 : :
3922 : 1051646 : if (maxval
3923 : 1051646 : && ccode == RSHIFT_EXPR
3924 : 97 : && crhs1 == lhs
3925 : 17 : && TREE_CODE (crhs2) == INTEGER_CST
3926 : 1051663 : && wi::to_widest (crhs2) == TYPE_PRECISION (TREE_TYPE (maxval)))
3927 : : {
3928 : 16 : tree shiftlhs = gimple_assign_lhs (use_stmt);
3929 : 16 : if (!shiftlhs)
3930 : : return 0;
3931 : 16 : use_operand_p use;
3932 : 16 : if (!single_imm_use (shiftlhs, &use, &cur_use_stmt))
3933 : : return 0;
3934 : 12 : if (gimple_code (cur_use_stmt) == GIMPLE_COND)
3935 : : {
3936 : 0 : ccode = gimple_cond_code (cur_use_stmt);
3937 : 0 : crhs1 = gimple_cond_lhs (cur_use_stmt);
3938 : 0 : crhs2 = gimple_cond_rhs (cur_use_stmt);
3939 : : }
3940 : 12 : else if (is_gimple_assign (cur_use_stmt))
3941 : : {
3942 : 12 : if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
3943 : : {
3944 : 0 : ccode = gimple_assign_rhs_code (cur_use_stmt);
3945 : 0 : crhs1 = gimple_assign_rhs1 (cur_use_stmt);
3946 : 0 : crhs2 = gimple_assign_rhs2 (cur_use_stmt);
3947 : : }
3948 : 12 : else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
3949 : : {
3950 : 0 : tree cond = gimple_assign_rhs1 (cur_use_stmt);
3951 : 0 : if (COMPARISON_CLASS_P (cond))
3952 : : {
3953 : 0 : ccode = TREE_CODE (cond);
3954 : 0 : crhs1 = TREE_OPERAND (cond, 0);
3955 : 0 : crhs2 = TREE_OPERAND (cond, 1);
3956 : : }
3957 : : else
3958 : : return 0;
3959 : : }
3960 : : else
3961 : : {
3962 : 12 : enum tree_code sc = gimple_assign_rhs_code (cur_use_stmt);
3963 : 12 : tree castlhs = gimple_assign_lhs (cur_use_stmt);
3964 : 12 : if (!CONVERT_EXPR_CODE_P (sc)
3965 : 12 : || !castlhs
3966 : 12 : || !INTEGRAL_TYPE_P (TREE_TYPE (castlhs))
3967 : 24 : || (TYPE_PRECISION (TREE_TYPE (castlhs))
3968 : 12 : > TYPE_PRECISION (TREE_TYPE (maxval))))
3969 : : return 0;
3970 : : return 1;
3971 : : }
3972 : : }
3973 : : else
3974 : : return 0;
3975 : 0 : if ((ccode != EQ_EXPR && ccode != NE_EXPR)
3976 : 0 : || crhs1 != shiftlhs
3977 : 0 : || !integer_zerop (crhs2))
3978 : 0 : return 0;
3979 : : return 1;
3980 : : }
3981 : :
3982 : 1051630 : if (TREE_CODE_CLASS (ccode) != tcc_comparison)
3983 : : return 0;
3984 : :
3985 : 613040 : switch (ccode)
3986 : : {
3987 : 116304 : case GT_EXPR:
3988 : 116304 : case LE_EXPR:
3989 : 116304 : if (maxval)
3990 : : {
3991 : : /* r = a + b; r > maxval or r <= maxval */
3992 : 45 : if (crhs1 == lhs
3993 : 44 : && TREE_CODE (crhs2) == INTEGER_CST
3994 : 67 : && tree_int_cst_equal (crhs2, maxval))
3995 : 12 : return ccode == GT_EXPR ? 1 : -1;
3996 : : break;
3997 : : }
3998 : : /* r = a - b; r > a or r <= a
3999 : : r = a + b; a > r or a <= r or b > r or b <= r. */
4000 : 116259 : if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
4001 : 116197 : || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2)
4002 : 8813 : && crhs2 == lhs))
4003 : 9215 : return ccode == GT_EXPR ? 1 : -1;
4004 : : /* r = ~a; b > r or b <= r. */
4005 : 107384 : if (code == BIT_NOT_EXPR && crhs2 == lhs)
4006 : : {
4007 : 190 : if (other)
4008 : 95 : *other = crhs1;
4009 : 222 : return ccode == GT_EXPR ? 1 : -1;
4010 : : }
4011 : : break;
4012 : 64739 : case LT_EXPR:
4013 : 64739 : case GE_EXPR:
4014 : 64739 : if (maxval)
4015 : : break;
4016 : : /* r = a - b; a < r or a >= r
4017 : : r = a + b; r < a or r >= a or r < b or r >= b. */
4018 : 64733 : if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
4019 : 64593 : || (code == PLUS_EXPR && crhs1 == lhs
4020 : 27627 : && (crhs2 == rhs1 || crhs2 == rhs2)))
4021 : 4022 : return ccode == LT_EXPR ? 1 : -1;
4022 : : /* r = ~a; r < b or r >= b. */
4023 : 60755 : if (code == BIT_NOT_EXPR && crhs1 == lhs)
4024 : : {
4025 : 167 : if (other)
4026 : 92 : *other = crhs2;
4027 : 219 : return ccode == LT_EXPR ? 1 : -1;
4028 : : }
4029 : : break;
4030 : 431997 : case EQ_EXPR:
4031 : 431997 : case NE_EXPR:
4032 : : /* r = a * b; _1 = r / a; _1 == b
4033 : : r = a * b; _1 = r / b; _1 == a
4034 : : r = a * b; _1 = r / a; _1 != b
4035 : : r = a * b; _1 = r / b; _1 != a. */
4036 : 431997 : if (code == MULT_EXPR)
4037 : : {
4038 : 293 : if (cast_stmt)
4039 : : {
4040 : 146 : if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
4041 : 146 : || (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
4042 : : {
4043 : 146 : use_stmt = cur_use_stmt;
4044 : 216 : return ccode == NE_EXPR ? 1 : -1;
4045 : : }
4046 : : }
4047 : 96 : else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
4048 : 147 : || (crhs2 == divlhs && crhs1 == multop))
4049 : : {
4050 : 147 : use_stmt = cur_use_stmt;
4051 : 223 : return ccode == NE_EXPR ? 1 : -1;
4052 : : }
4053 : : }
4054 : : break;
4055 : : default:
4056 : : break;
4057 : : }
4058 : : return 0;
4059 : : }
4060 : :
4061 : : extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
4062 : : extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree));
4063 : : extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree));
4064 : : extern bool gimple_unsigned_integer_sat_mul (tree, tree*, tree (*)(tree));
4065 : :
4066 : : extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
4067 : : extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
4068 : : extern bool gimple_signed_integer_sat_trunc (tree, tree*, tree (*)(tree));
4069 : :
4070 : : static void
4071 : 156 : build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi,
4072 : : internal_fn fn, tree lhs,
4073 : : tree op_0, tree op_1)
4074 : : {
4075 : 156 : if (direct_internal_fn_supported_p (fn, TREE_TYPE (lhs), OPTIMIZE_FOR_BOTH))
4076 : : {
4077 : 156 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4078 : 156 : gimple_call_set_lhs (call, lhs);
4079 : 156 : gsi_replace (gsi, call, /* update_eh_info */ true);
4080 : : }
4081 : 156 : }
4082 : :
4083 : : static bool
4084 : 51 : build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi,
4085 : : internal_fn fn, tree lhs,
4086 : : tree op_0, tree op_1)
4087 : : {
4088 : 51 : if (!direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
4089 : : return false;
4090 : :
4091 : 43 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4092 : 43 : gimple_call_set_lhs (call, lhs);
4093 : 43 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4094 : :
4095 : 43 : return true;
4096 : : }
4097 : :
4098 : : /*
4099 : : * Try to match saturation unsigned add with assign.
4100 : : * _7 = _4 + _6;
4101 : : * _8 = _4 > _7;
4102 : : * _9 = (long unsigned int) _8;
4103 : : * _10 = -_9;
4104 : : * _12 = _7 | _10;
4105 : : * =>
4106 : : * _12 = .SAT_ADD (_4, _6);
4107 : : *
4108 : : * Try to match IMM=-1 saturation signed add with assign.
4109 : : * <bb 2> [local count: 1073741824]:
4110 : : * x.0_1 = (unsigned char) x_5(D);
4111 : : * _3 = -x.0_1;
4112 : : * _10 = (signed char) _3;
4113 : : * _8 = x_5(D) & _10;
4114 : : * if (_8 < 0)
4115 : : * goto <bb 4>; [1.40%]
4116 : : * else
4117 : : * goto <bb 3>; [98.60%]
4118 : : * <bb 3> [local count: 434070867]:
4119 : : * _2 = x.0_1 + 255;
4120 : : * <bb 4> [local count: 1073741824]:
4121 : : * # _9 = PHI <_2(3), 128(2)>
4122 : : * _4 = (int8_t) _9;
4123 : : * =>
4124 : : * _4 = .SAT_ADD (x_5, -1); */
4125 : :
4126 : : static void
4127 : 4835024 : match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
4128 : : {
4129 : 4835024 : tree ops[2];
4130 : 4835024 : tree lhs = gimple_assign_lhs (stmt);
4131 : :
4132 : 4835024 : if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
4133 : 4835024 : || gimple_signed_integer_sat_add (lhs, ops, NULL))
4134 : 34 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
4135 : : ops[0], ops[1]);
4136 : 4835024 : }
4137 : :
4138 : : /*
4139 : : * Try to match saturation add with PHI.
4140 : : * For unsigned integer:
4141 : : * <bb 2> :
4142 : : * _1 = x_3(D) + y_4(D);
4143 : : * if (_1 >= x_3(D))
4144 : : * goto <bb 3>; [INV]
4145 : : * else
4146 : : * goto <bb 4>; [INV]
4147 : : *
4148 : : * <bb 3> :
4149 : : *
4150 : : * <bb 4> :
4151 : : * # _2 = PHI <255(2), _1(3)>
4152 : : * =>
4153 : : * <bb 4> [local count: 1073741824]:
4154 : : * _2 = .SAT_ADD (x_4(D), y_5(D));
4155 : : *
4156 : : * For signed integer:
4157 : : * x.0_1 = (long unsigned int) x_7(D);
4158 : : * y.1_2 = (long unsigned int) y_8(D);
4159 : : * _3 = x.0_1 + y.1_2;
4160 : : * sum_9 = (int64_t) _3;
4161 : : * _4 = x_7(D) ^ y_8(D);
4162 : : * _5 = x_7(D) ^ sum_9;
4163 : : * _15 = ~_4;
4164 : : * _16 = _5 & _15;
4165 : : * if (_16 < 0)
4166 : : * goto <bb 3>; [41.00%]
4167 : : * else
4168 : : * goto <bb 4>; [59.00%]
4169 : : * _11 = x_7(D) < 0;
4170 : : * _12 = (long int) _11;
4171 : : * _13 = -_12;
4172 : : * _14 = _13 ^ 9223372036854775807;
4173 : : * # _6 = PHI <_14(3), sum_9(2)>
4174 : : * =>
4175 : : * _6 = .SAT_ADD (x_5(D), y_6(D)); [tail call] */
4176 : :
4177 : : static bool
4178 : 4507571 : match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
4179 : : {
4180 : 4507571 : if (gimple_phi_num_args (phi) != 2)
4181 : : return false;
4182 : :
4183 : 3698210 : tree ops[2];
4184 : 3698210 : tree phi_result = gimple_phi_result (phi);
4185 : :
4186 : 3698210 : if (!gimple_unsigned_integer_sat_add (phi_result, ops, NULL)
4187 : 3698210 : && !gimple_signed_integer_sat_add (phi_result, ops, NULL))
4188 : : return false;
4189 : :
4190 : 21 : if (!TYPE_UNSIGNED (TREE_TYPE (ops[0])) && TREE_CODE (ops[1]) == INTEGER_CST)
4191 : 0 : ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
4192 : :
4193 : 21 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_ADD,
4194 : : phi_result, ops[0],
4195 : 21 : ops[1]);
4196 : : }
4197 : :
4198 : : /*
4199 : : * Try to match saturation unsigned sub.
4200 : : * _1 = _4 >= _5;
4201 : : * _3 = _4 - _5;
4202 : : * _6 = _1 ? _3 : 0;
4203 : : * =>
4204 : : * _6 = .SAT_SUB (_4, _5); */
4205 : :
4206 : : static void
4207 : 3300084 : match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
4208 : : {
4209 : 3300084 : tree ops[2];
4210 : 3300084 : tree lhs = gimple_assign_lhs (stmt);
4211 : :
4212 : 3300084 : if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
4213 : 122 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_SUB, lhs,
4214 : : ops[0], ops[1]);
4215 : 3300084 : }
4216 : :
4217 : : /*
4218 : : * Try to match saturation unsigned mul.
4219 : : * _1 = (unsigned int) a_6(D);
4220 : : * _2 = (unsigned int) b_7(D);
4221 : : * x_8 = _1 * _2;
4222 : : * overflow_9 = x_8 > 255;
4223 : : * _3 = (unsigned char) overflow_9;
4224 : : * _4 = -_3;
4225 : : * _5 = (unsigned char) x_8;
4226 : : * _10 = _4 | _5;
4227 : : * =>
4228 : : * _10 = .SAT_SUB (a_6, b_7); */
4229 : :
4230 : : static void
4231 : 2595205 : match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt)
4232 : : {
4233 : 2595205 : tree ops[2];
4234 : 2595205 : tree lhs = gimple_assign_lhs (stmt);
4235 : :
4236 : 2595205 : if (gimple_unsigned_integer_sat_mul (lhs, ops, NULL))
4237 : 0 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_MUL, lhs,
4238 : : ops[0], ops[1]);
4239 : 2595205 : }
4240 : :
4241 : : /* Try to match saturation unsigned mul, aka:
4242 : : _6 = .MUL_OVERFLOW (a_4(D), b_5(D));
4243 : : _2 = IMAGPART_EXPR <_6>;
4244 : : if (_2 != 0)
4245 : : goto <bb 4>; [35.00%]
4246 : : else
4247 : : goto <bb 3>; [65.00%]
4248 : :
4249 : : <bb 3> [local count: 697932184]:
4250 : : _1 = REALPART_EXPR <_6>;
4251 : :
4252 : : <bb 4> [local count: 1073741824]:
4253 : : # _3 = PHI <18446744073709551615(2), _1(3)>
4254 : : =>
4255 : : _3 = .SAT_MUL (a_4(D), b_5(D)); */
4256 : :
4257 : : static bool
4258 : 4507528 : match_saturation_mul (gimple_stmt_iterator *gsi, gphi *phi)
4259 : : {
4260 : 4507528 : if (gimple_phi_num_args (phi) != 2)
4261 : : return false;
4262 : :
4263 : 3698167 : tree ops[2];
4264 : 3698167 : tree phi_result = gimple_phi_result (phi);
4265 : :
4266 : 3698167 : if (!gimple_unsigned_integer_sat_mul (phi_result, ops, NULL))
4267 : : return false;
4268 : :
4269 : 0 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_MUL,
4270 : : phi_result, ops[0],
4271 : 0 : ops[1]);
4272 : : }
4273 : :
4274 : : /*
4275 : : * Try to match saturation unsigned sub.
4276 : : * <bb 2> [local count: 1073741824]:
4277 : : * if (x_2(D) > y_3(D))
4278 : : * goto <bb 3>; [50.00%]
4279 : : * else
4280 : : * goto <bb 4>; [50.00%]
4281 : : *
4282 : : * <bb 3> [local count: 536870912]:
4283 : : * _4 = x_2(D) - y_3(D);
4284 : : *
4285 : : * <bb 4> [local count: 1073741824]:
4286 : : * # _1 = PHI <0(2), _4(3)>
4287 : : * =>
4288 : : * <bb 4> [local count: 1073741824]:
4289 : : * _1 = .SAT_SUB (x_2(D), y_3(D)); */
4290 : : static bool
4291 : 4507554 : match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
4292 : : {
4293 : 4507554 : if (gimple_phi_num_args (phi) != 2)
4294 : : return false;
4295 : :
4296 : 3698193 : tree ops[2];
4297 : 3698193 : tree phi_result = gimple_phi_result (phi);
4298 : :
4299 : 3698193 : if (!gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
4300 : 3698193 : && !gimple_signed_integer_sat_sub (phi_result, ops, NULL))
4301 : : return false;
4302 : :
4303 : 30 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_SUB,
4304 : : phi_result, ops[0],
4305 : 30 : ops[1]);
4306 : : }
4307 : :
4308 : : /*
4309 : : * Try to match saturation unsigned sub.
4310 : : * uint16_t x_4(D);
4311 : : * uint8_t _6;
4312 : : * overflow_5 = x_4(D) > 255;
4313 : : * _1 = (unsigned char) x_4(D);
4314 : : * _2 = (unsigned char) overflow_5;
4315 : : * _3 = -_2;
4316 : : * _6 = _1 | _3;
4317 : : * =>
4318 : : * _6 = .SAT_TRUNC (x_4(D));
4319 : : * */
4320 : : static void
4321 : 2595205 : match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
4322 : : {
4323 : 2595205 : tree ops[1];
4324 : 2595205 : tree lhs = gimple_assign_lhs (stmt);
4325 : 2595205 : tree type = TREE_TYPE (lhs);
4326 : :
4327 : 2595205 : if (gimple_unsigned_integer_sat_trunc (lhs, ops, NULL)
4328 : 2595305 : && direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4329 : 100 : tree_pair (type, TREE_TYPE (ops[0])),
4330 : : OPTIMIZE_FOR_BOTH))
4331 : : {
4332 : 73 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4333 : 73 : gimple_call_set_lhs (call, lhs);
4334 : 73 : gsi_replace (gsi, call, /* update_eh_info */ true);
4335 : : }
4336 : 2595205 : }
4337 : :
4338 : : /*
4339 : : * Try to match saturation truncate.
4340 : : * Aka:
4341 : : * x.0_1 = (unsigned long) x_4(D);
4342 : : * _2 = x.0_1 + 2147483648;
4343 : : * if (_2 > 4294967295)
4344 : : * goto <bb 4>; [50.00%]
4345 : : * else
4346 : : * goto <bb 3>; [50.00%]
4347 : : * ;; succ: 4
4348 : : * ;; 3
4349 : : *
4350 : : * ;; basic block 3, loop depth 0
4351 : : * ;; pred: 2
4352 : : * trunc_5 = (int32_t) x_4(D);
4353 : : * goto <bb 5>; [100.00%]
4354 : : * ;; succ: 5
4355 : : *
4356 : : * ;; basic block 4, loop depth 0
4357 : : * ;; pred: 2
4358 : : * _7 = x_4(D) < 0;
4359 : : * _8 = (int) _7;
4360 : : * _9 = -_8;
4361 : : * _10 = _9 ^ 2147483647;
4362 : : * ;; succ: 5
4363 : : *
4364 : : * ;; basic block 5, loop depth 0
4365 : : * ;; pred: 3
4366 : : * ;; 4
4367 : : * # _3 = PHI <trunc_5(3), _10(4)>
4368 : : * =>
4369 : : * _6 = .SAT_TRUNC (x_4(D));
4370 : : */
4371 : :
4372 : : static bool
4373 : 4507528 : match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
4374 : : {
4375 : 4507528 : if (gimple_phi_num_args (phi) != 2)
4376 : : return false;
4377 : :
4378 : 3698167 : tree ops[1];
4379 : 3698167 : tree phi_result = gimple_phi_result (phi);
4380 : 3698167 : tree type = TREE_TYPE (phi_result);
4381 : :
4382 : 3698167 : if (!gimple_unsigned_integer_sat_trunc (phi_result, ops, NULL)
4383 : 3698167 : && !gimple_signed_integer_sat_trunc (phi_result, ops, NULL))
4384 : : return false;
4385 : :
4386 : 0 : if (!direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4387 : 0 : tree_pair (type, TREE_TYPE (ops[0])),
4388 : : OPTIMIZE_FOR_BOTH))
4389 : : return false;
4390 : :
4391 : 0 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4392 : 0 : gimple_call_set_lhs (call, phi_result);
4393 : 0 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4394 : :
4395 : 0 : return true;
4396 : : }
4397 : :
4398 : : /* Recognize for unsigned x
4399 : : x = y - z;
4400 : : if (x > y)
4401 : : where there are other uses of x and replace it with
4402 : : _7 = .SUB_OVERFLOW (y, z);
4403 : : x = REALPART_EXPR <_7>;
4404 : : _8 = IMAGPART_EXPR <_7>;
4405 : : if (_8)
4406 : : and similarly for addition.
4407 : :
4408 : : Also recognize:
4409 : : yc = (type) y;
4410 : : zc = (type) z;
4411 : : x = yc + zc;
4412 : : if (x > max)
4413 : : where y and z have unsigned types with maximum max
4414 : : and there are other uses of x and all of those cast x
4415 : : back to that unsigned type and again replace it with
4416 : : _7 = .ADD_OVERFLOW (y, z);
4417 : : _9 = REALPART_EXPR <_7>;
4418 : : _8 = IMAGPART_EXPR <_7>;
4419 : : if (_8)
4420 : : and replace (utype) x with _9.
4421 : : Or with x >> popcount (max) instead of x > max.
4422 : :
4423 : : Also recognize:
4424 : : x = ~z;
4425 : : if (y > x)
4426 : : and replace it with
4427 : : _7 = .ADD_OVERFLOW (y, z);
4428 : : _8 = IMAGPART_EXPR <_7>;
4429 : : if (_8)
4430 : :
4431 : : And also recognize:
4432 : : z = x * y;
4433 : : if (x != 0)
4434 : : goto <bb 3>; [50.00%]
4435 : : else
4436 : : goto <bb 4>; [50.00%]
4437 : :
4438 : : <bb 3> [local count: 536870913]:
4439 : : _2 = z / x;
4440 : : _9 = _2 != y;
4441 : : _10 = (int) _9;
4442 : :
4443 : : <bb 4> [local count: 1073741824]:
4444 : : # iftmp.0_3 = PHI <_10(3), 0(2)>
4445 : : and replace it with
4446 : : _7 = .MUL_OVERFLOW (x, y);
4447 : : z = IMAGPART_EXPR <_7>;
4448 : : _8 = IMAGPART_EXPR <_7>;
4449 : : _9 = _8 != 0;
4450 : : iftmp.0_3 = (int) _9; */
4451 : :
4452 : : static bool
4453 : 3270735 : match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
4454 : : enum tree_code code, bool *cfg_changed)
4455 : : {
4456 : 3270735 : tree lhs = gimple_assign_lhs (stmt);
4457 : 3270735 : tree type = TREE_TYPE (lhs);
4458 : 3270735 : use_operand_p use_p;
4459 : 3270735 : imm_use_iterator iter;
4460 : 3270735 : bool use_seen = false;
4461 : 3270735 : bool ovf_use_seen = false;
4462 : 3270735 : gimple *use_stmt;
4463 : 3270735 : gimple *add_stmt = NULL;
4464 : 3270735 : bool add_first = false;
4465 : 3270735 : gimple *cond_stmt = NULL;
4466 : 3270735 : gimple *cast_stmt = NULL;
4467 : 3270735 : tree cast_lhs = NULL_TREE;
4468 : :
4469 : 3270735 : gcc_checking_assert (code == PLUS_EXPR
4470 : : || code == MINUS_EXPR
4471 : : || code == MULT_EXPR
4472 : : || code == BIT_NOT_EXPR);
4473 : 3270735 : if (!INTEGRAL_TYPE_P (type)
4474 : 2754448 : || !TYPE_UNSIGNED (type)
4475 : 1919205 : || has_zero_uses (lhs)
4476 : 3270735 : || (code != PLUS_EXPR
4477 : 1918959 : && code != MULT_EXPR
4478 : 180592 : && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab,
4479 : 156155 : TYPE_MODE (type)) == CODE_FOR_nothing))
4480 : 1353877 : return false;
4481 : :
4482 : 1916858 : tree rhs1 = gimple_assign_rhs1 (stmt);
4483 : 1916858 : tree rhs2 = gimple_assign_rhs2 (stmt);
4484 : 5178798 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4485 : : {
4486 : 3268261 : use_stmt = USE_STMT (use_p);
4487 : 3268261 : if (is_gimple_debug (use_stmt))
4488 : 462438 : continue;
4489 : :
4490 : 2805823 : tree other = NULL_TREE;
4491 : 2805823 : if (arith_overflow_check_p (stmt, NULL, use_stmt, NULL_TREE, &other))
4492 : : {
4493 : 6814 : if (code == BIT_NOT_EXPR)
4494 : : {
4495 : 187 : gcc_assert (other);
4496 : 187 : if (TREE_CODE (other) != SSA_NAME)
4497 : 0 : return false;
4498 : 187 : if (rhs2 == NULL)
4499 : 187 : rhs2 = other;
4500 : : else
4501 : : return false;
4502 : 187 : cond_stmt = use_stmt;
4503 : : }
4504 : : ovf_use_seen = true;
4505 : : }
4506 : : else
4507 : : {
4508 : 2799009 : use_seen = true;
4509 : 2799009 : if (code == MULT_EXPR
4510 : 2799009 : && cast_stmt == NULL
4511 : 2799009 : && gimple_assign_cast_p (use_stmt))
4512 : : {
4513 : 31552 : cast_lhs = gimple_assign_lhs (use_stmt);
4514 : 63104 : if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
4515 : 31014 : && !TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
4516 : 59703 : && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
4517 : 28151 : == TYPE_PRECISION (TREE_TYPE (lhs))))
4518 : : cast_stmt = use_stmt;
4519 : : else
4520 : : cast_lhs = NULL_TREE;
4521 : : }
4522 : : }
4523 : 2805823 : if (ovf_use_seen && use_seen)
4524 : : break;
4525 : : }
4526 : :
4527 : 1916858 : if (!ovf_use_seen
4528 : 1916858 : && code == MULT_EXPR
4529 : 441181 : && cast_stmt)
4530 : : {
4531 : 27702 : if (TREE_CODE (rhs1) != SSA_NAME
4532 : 27702 : || (TREE_CODE (rhs2) != SSA_NAME && TREE_CODE (rhs2) != INTEGER_CST))
4533 : : return false;
4534 : 62980 : FOR_EACH_IMM_USE_FAST (use_p, iter, cast_lhs)
4535 : : {
4536 : 35278 : use_stmt = USE_STMT (use_p);
4537 : 35278 : if (is_gimple_debug (use_stmt))
4538 : 1153 : continue;
4539 : :
4540 : 34125 : if (arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4541 : : NULL_TREE, NULL))
4542 : 35278 : ovf_use_seen = true;
4543 : : }
4544 : : }
4545 : : else
4546 : : {
4547 : : cast_stmt = NULL;
4548 : : cast_lhs = NULL_TREE;
4549 : : }
4550 : :
4551 : 1916858 : tree maxval = NULL_TREE;
4552 : 1916858 : if (!ovf_use_seen
4553 : 13630 : || (code != MULT_EXPR && (code == BIT_NOT_EXPR ? use_seen : !use_seen))
4554 : 6439 : || (code == PLUS_EXPR
4555 : 6169 : && optab_handler (uaddv4_optab,
4556 : 6169 : TYPE_MODE (type)) == CODE_FOR_nothing)
4557 : 1930186 : || (code == MULT_EXPR
4558 : 221 : && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
4559 : 148 : TYPE_MODE (type)) == CODE_FOR_nothing
4560 : 3 : && (use_seen
4561 : 3 : || cast_stmt
4562 : 0 : || !can_mult_highpart_p (TYPE_MODE (type), true))))
4563 : : {
4564 : 1910274 : if (code != PLUS_EXPR)
4565 : : return false;
4566 : 1315381 : if (TREE_CODE (rhs1) != SSA_NAME
4567 : 1315381 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
4568 : : return false;
4569 : 323360 : rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
4570 : 323360 : tree type1 = TREE_TYPE (rhs1);
4571 : 323360 : if (!INTEGRAL_TYPE_P (type1)
4572 : 176086 : || !TYPE_UNSIGNED (type1)
4573 : 41063 : || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
4574 : 341100 : || (TYPE_PRECISION (type1)
4575 : 35480 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
4576 : 311341 : return false;
4577 : 12019 : if (TREE_CODE (rhs2) == INTEGER_CST)
4578 : : {
4579 : 4137 : if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
4580 : 4137 : TYPE_PRECISION (type1),
4581 : 8274 : UNSIGNED), 0))
4582 : : return false;
4583 : 1253 : rhs2 = fold_convert (type1, rhs2);
4584 : : }
4585 : : else
4586 : : {
4587 : 7882 : if (TREE_CODE (rhs2) != SSA_NAME
4588 : 7882 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
4589 : : return false;
4590 : 2810 : rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
4591 : 2810 : tree type2 = TREE_TYPE (rhs2);
4592 : 2810 : if (!INTEGRAL_TYPE_P (type2)
4593 : 1142 : || !TYPE_UNSIGNED (type2)
4594 : 395 : || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
4595 : 3161 : || (TYPE_PRECISION (type2)
4596 : 702 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
4597 : 2472 : return false;
4598 : : }
4599 : 1591 : if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
4600 : : type = type1;
4601 : : else
4602 : 5 : type = TREE_TYPE (rhs2);
4603 : :
4604 : 1591 : if (TREE_CODE (type) != INTEGER_TYPE
4605 : 3182 : || optab_handler (uaddv4_optab,
4606 : 1591 : TYPE_MODE (type)) == CODE_FOR_nothing)
4607 : 0 : return false;
4608 : :
4609 : 1591 : maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
4610 : : UNSIGNED));
4611 : 1591 : ovf_use_seen = false;
4612 : 1591 : use_seen = false;
4613 : 1591 : basic_block use_bb = NULL;
4614 : 1663 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4615 : : {
4616 : 1603 : use_stmt = USE_STMT (use_p);
4617 : 1603 : if (is_gimple_debug (use_stmt))
4618 : 8 : continue;
4619 : :
4620 : 1595 : if (arith_overflow_check_p (stmt, NULL, use_stmt, maxval, NULL))
4621 : : {
4622 : 12 : ovf_use_seen = true;
4623 : 12 : use_bb = gimple_bb (use_stmt);
4624 : : }
4625 : : else
4626 : : {
4627 : 1583 : if (!gimple_assign_cast_p (use_stmt)
4628 : 1583 : || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
4629 : : return false;
4630 : 106 : tree use_lhs = gimple_assign_lhs (use_stmt);
4631 : 212 : if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
4632 : 212 : || (TYPE_PRECISION (TREE_TYPE (use_lhs))
4633 : 106 : > TYPE_PRECISION (type)))
4634 : : return false;
4635 : : use_seen = true;
4636 : : }
4637 : : }
4638 : 60 : if (!ovf_use_seen)
4639 : : return false;
4640 : 12 : if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
4641 : : {
4642 : 2 : if (!use_seen)
4643 : : return false;
4644 : 2 : tree new_rhs1 = make_ssa_name (type);
4645 : 2 : gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
4646 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4647 : 2 : rhs1 = new_rhs1;
4648 : : }
4649 : 10 : else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
4650 : : {
4651 : 2 : if (!use_seen)
4652 : : return false;
4653 : 2 : tree new_rhs2 = make_ssa_name (type);
4654 : 2 : gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
4655 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4656 : 2 : rhs2 = new_rhs2;
4657 : : }
4658 : 8 : else if (!use_seen)
4659 : : {
4660 : : /* If there are no uses of the wider addition, check if
4661 : : forwprop has not created a narrower addition.
4662 : : Require it to be in the same bb as the overflow check. */
4663 : 10 : FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
4664 : : {
4665 : 10 : use_stmt = USE_STMT (use_p);
4666 : 10 : if (is_gimple_debug (use_stmt))
4667 : 0 : continue;
4668 : :
4669 : 10 : if (use_stmt == stmt)
4670 : 0 : continue;
4671 : :
4672 : 10 : if (!is_gimple_assign (use_stmt)
4673 : 10 : || gimple_bb (use_stmt) != use_bb
4674 : 20 : || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
4675 : 2 : continue;
4676 : :
4677 : 8 : if (gimple_assign_rhs1 (use_stmt) == rhs1)
4678 : : {
4679 : 8 : if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
4680 : : rhs2, 0))
4681 : 0 : continue;
4682 : : }
4683 : 0 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
4684 : : {
4685 : 0 : if (gimple_assign_rhs1 (use_stmt) != rhs2)
4686 : 0 : continue;
4687 : : }
4688 : : else
4689 : 0 : continue;
4690 : :
4691 : 8 : add_stmt = use_stmt;
4692 : 8 : break;
4693 : : }
4694 : 8 : if (add_stmt == NULL)
4695 : : return false;
4696 : :
4697 : : /* If stmt and add_stmt are in the same bb, we need to find out
4698 : : which one is earlier. If they are in different bbs, we've
4699 : : checked add_stmt is in the same bb as one of the uses of the
4700 : : stmt lhs, so stmt needs to dominate add_stmt too. */
4701 : 8 : if (gimple_bb (stmt) == gimple_bb (add_stmt))
4702 : : {
4703 : 8 : gimple_stmt_iterator gsif = *gsi;
4704 : 8 : gimple_stmt_iterator gsib = *gsi;
4705 : 8 : int i;
4706 : : /* Search both forward and backward from stmt and have a small
4707 : : upper bound. */
4708 : 20 : for (i = 0; i < 128; i++)
4709 : : {
4710 : 20 : if (!gsi_end_p (gsib))
4711 : : {
4712 : 18 : gsi_prev_nondebug (&gsib);
4713 : 18 : if (gsi_stmt (gsib) == add_stmt)
4714 : : {
4715 : : add_first = true;
4716 : : break;
4717 : : }
4718 : : }
4719 : 2 : else if (gsi_end_p (gsif))
4720 : : break;
4721 : 18 : if (!gsi_end_p (gsif))
4722 : : {
4723 : 18 : gsi_next_nondebug (&gsif);
4724 : 18 : if (gsi_stmt (gsif) == add_stmt)
4725 : : break;
4726 : : }
4727 : : }
4728 : 8 : if (i == 128)
4729 : 0 : return false;
4730 : 8 : if (add_first)
4731 : 2 : *gsi = gsi_for_stmt (add_stmt);
4732 : : }
4733 : : }
4734 : : }
4735 : :
4736 : 6596 : if (code == BIT_NOT_EXPR)
4737 : 170 : *gsi = gsi_for_stmt (cond_stmt);
4738 : :
4739 : 6596 : auto_vec<gimple *, 8> mul_stmts;
4740 : 6596 : if (code == MULT_EXPR && cast_stmt)
4741 : : {
4742 : 75 : type = TREE_TYPE (cast_lhs);
4743 : 75 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
4744 : 75 : if (gimple_assign_cast_p (g)
4745 : 38 : && useless_type_conversion_p (type,
4746 : 38 : TREE_TYPE (gimple_assign_rhs1 (g)))
4747 : 113 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4748 : : rhs1 = gimple_assign_rhs1 (g);
4749 : : else
4750 : : {
4751 : 37 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs1);
4752 : 37 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4753 : 37 : rhs1 = gimple_assign_lhs (g);
4754 : 37 : mul_stmts.quick_push (g);
4755 : : }
4756 : 75 : if (TREE_CODE (rhs2) == INTEGER_CST)
4757 : 32 : rhs2 = fold_convert (type, rhs2);
4758 : : else
4759 : : {
4760 : 43 : g = SSA_NAME_DEF_STMT (rhs2);
4761 : 43 : if (gimple_assign_cast_p (g)
4762 : 22 : && useless_type_conversion_p (type,
4763 : 22 : TREE_TYPE (gimple_assign_rhs1 (g)))
4764 : 65 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4765 : : rhs2 = gimple_assign_rhs1 (g);
4766 : : else
4767 : : {
4768 : 21 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs2);
4769 : 21 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4770 : 21 : rhs2 = gimple_assign_lhs (g);
4771 : 21 : mul_stmts.quick_push (g);
4772 : : }
4773 : : }
4774 : : }
4775 : 6596 : tree ctype = build_complex_type (type);
4776 : 13047 : gcall *g = gimple_build_call_internal (code == MULT_EXPR
4777 : : ? IFN_MUL_OVERFLOW
4778 : : : code != MINUS_EXPR
4779 : 6451 : ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
4780 : : 2, rhs1, rhs2);
4781 : 6596 : tree ctmp = make_ssa_name (ctype);
4782 : 6596 : gimple_call_set_lhs (g, ctmp);
4783 : 6596 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4784 : 6596 : tree new_lhs = (maxval || cast_stmt) ? make_ssa_name (type) : lhs;
4785 : 6596 : gassign *g2;
4786 : 6596 : if (code != BIT_NOT_EXPR)
4787 : : {
4788 : 6426 : g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
4789 : : build1 (REALPART_EXPR, type, ctmp));
4790 : 6426 : if (maxval || cast_stmt)
4791 : : {
4792 : 87 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4793 : 87 : if (add_first)
4794 : 2 : *gsi = gsi_for_stmt (stmt);
4795 : : }
4796 : : else
4797 : 6339 : gsi_replace (gsi, g2, true);
4798 : 6426 : if (code == MULT_EXPR)
4799 : : {
4800 : 145 : mul_stmts.quick_push (g);
4801 : 145 : mul_stmts.quick_push (g2);
4802 : 145 : if (cast_stmt)
4803 : : {
4804 : 75 : g2 = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
4805 : 75 : gsi_replace (gsi, g2, true);
4806 : 75 : mul_stmts.quick_push (g2);
4807 : : }
4808 : : }
4809 : : }
4810 : 6596 : tree ovf = make_ssa_name (type);
4811 : 6596 : g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
4812 : : build1 (IMAGPART_EXPR, type, ctmp));
4813 : 6596 : if (code != BIT_NOT_EXPR)
4814 : 6426 : gsi_insert_after (gsi, g2, GSI_NEW_STMT);
4815 : : else
4816 : 170 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4817 : 6596 : if (code == MULT_EXPR)
4818 : 145 : mul_stmts.quick_push (g2);
4819 : :
4820 : 34428 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
4821 : : {
4822 : 21311 : if (is_gimple_debug (use_stmt))
4823 : 5077 : continue;
4824 : :
4825 : 16234 : gimple *orig_use_stmt = use_stmt;
4826 : 16234 : int ovf_use = arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4827 : : maxval, NULL);
4828 : 16234 : if (ovf_use == 0)
4829 : : {
4830 : 9608 : gcc_assert (code != BIT_NOT_EXPR);
4831 : 9608 : if (maxval)
4832 : : {
4833 : 4 : tree use_lhs = gimple_assign_lhs (use_stmt);
4834 : 4 : gimple_assign_set_rhs1 (use_stmt, new_lhs);
4835 : 4 : if (useless_type_conversion_p (TREE_TYPE (use_lhs),
4836 : 4 : TREE_TYPE (new_lhs)))
4837 : 4 : gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
4838 : 4 : update_stmt (use_stmt);
4839 : : }
4840 : 9608 : continue;
4841 : 9608 : }
4842 : 6626 : if (gimple_code (use_stmt) == GIMPLE_COND)
4843 : : {
4844 : 4319 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4845 : 4319 : gimple_cond_set_lhs (cond_stmt, ovf);
4846 : 4319 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4847 : 4471 : gimple_cond_set_code (cond_stmt, ovf_use == 1 ? NE_EXPR : EQ_EXPR);
4848 : : }
4849 : : else
4850 : : {
4851 : 2307 : gcc_checking_assert (is_gimple_assign (use_stmt));
4852 : 2307 : if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
4853 : : {
4854 : 2307 : if (gimple_assign_rhs_code (use_stmt) == RSHIFT_EXPR)
4855 : : {
4856 : 6 : g2 = gimple_build_assign (make_ssa_name (boolean_type_node),
4857 : : ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4858 : : ovf, build_int_cst (type, 0));
4859 : 6 : gimple_stmt_iterator gsiu = gsi_for_stmt (use_stmt);
4860 : 6 : gsi_insert_before (&gsiu, g2, GSI_SAME_STMT);
4861 : 6 : gimple_assign_set_rhs_with_ops (&gsiu, NOP_EXPR,
4862 : : gimple_assign_lhs (g2));
4863 : 6 : update_stmt (use_stmt);
4864 : 6 : use_operand_p use;
4865 : 6 : single_imm_use (gimple_assign_lhs (use_stmt), &use,
4866 : : &use_stmt);
4867 : 6 : if (gimple_code (use_stmt) == GIMPLE_COND)
4868 : : {
4869 : 0 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4870 : 0 : gimple_cond_set_lhs (cond_stmt, ovf);
4871 : 0 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4872 : : }
4873 : : else
4874 : : {
4875 : 6 : gcc_checking_assert (is_gimple_assign (use_stmt));
4876 : 6 : if (gimple_assign_rhs_class (use_stmt)
4877 : : == GIMPLE_BINARY_RHS)
4878 : : {
4879 : 0 : gimple_assign_set_rhs1 (use_stmt, ovf);
4880 : 0 : gimple_assign_set_rhs2 (use_stmt,
4881 : : build_int_cst (type, 0));
4882 : : }
4883 : 6 : else if (gimple_assign_cast_p (use_stmt))
4884 : 6 : gimple_assign_set_rhs1 (use_stmt, ovf);
4885 : : else
4886 : : {
4887 : 0 : tree_code sc = gimple_assign_rhs_code (use_stmt);
4888 : 0 : gcc_checking_assert (sc == COND_EXPR);
4889 : 0 : tree cond = gimple_assign_rhs1 (use_stmt);
4890 : 0 : cond = build2 (TREE_CODE (cond),
4891 : : boolean_type_node, ovf,
4892 : : build_int_cst (type, 0));
4893 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4894 : : }
4895 : : }
4896 : 6 : update_stmt (use_stmt);
4897 : 6 : gsi_remove (&gsiu, true);
4898 : 6 : gsiu = gsi_for_stmt (g2);
4899 : 6 : gsi_remove (&gsiu, true);
4900 : 6 : continue;
4901 : 6 : }
4902 : : else
4903 : : {
4904 : 2301 : gimple_assign_set_rhs1 (use_stmt, ovf);
4905 : 2301 : gimple_assign_set_rhs2 (use_stmt, build_int_cst (type, 0));
4906 : 2450 : gimple_assign_set_rhs_code (use_stmt,
4907 : : ovf_use == 1
4908 : : ? NE_EXPR : EQ_EXPR);
4909 : : }
4910 : : }
4911 : : else
4912 : : {
4913 : 0 : gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
4914 : : == COND_EXPR);
4915 : 0 : tree cond = build2 (ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4916 : : boolean_type_node, ovf,
4917 : : build_int_cst (type, 0));
4918 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4919 : : }
4920 : : }
4921 : 6620 : update_stmt (use_stmt);
4922 : 6620 : if (code == MULT_EXPR && use_stmt != orig_use_stmt)
4923 : : {
4924 : 145 : gimple_stmt_iterator gsi2 = gsi_for_stmt (orig_use_stmt);
4925 : 145 : maybe_optimize_guarding_check (mul_stmts, use_stmt, orig_use_stmt,
4926 : : cfg_changed);
4927 : 145 : use_operand_p use;
4928 : 145 : gimple *cast_stmt;
4929 : 145 : if (single_imm_use (gimple_assign_lhs (orig_use_stmt), &use,
4930 : : &cast_stmt)
4931 : 145 : && gimple_assign_cast_p (cast_stmt))
4932 : : {
4933 : 2 : gimple_stmt_iterator gsi3 = gsi_for_stmt (cast_stmt);
4934 : 2 : gsi_remove (&gsi3, true);
4935 : 2 : release_ssa_name (gimple_assign_lhs (cast_stmt));
4936 : : }
4937 : 145 : gsi_remove (&gsi2, true);
4938 : 145 : release_ssa_name (gimple_assign_lhs (orig_use_stmt));
4939 : : }
4940 : 6596 : }
4941 : 6596 : if (maxval)
4942 : : {
4943 : 12 : gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
4944 : 12 : gsi_remove (&gsi2, true);
4945 : 12 : if (add_stmt)
4946 : : {
4947 : 8 : gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
4948 : : new_lhs);
4949 : 8 : gsi2 = gsi_for_stmt (add_stmt);
4950 : 8 : gsi_replace (&gsi2, g, true);
4951 : : }
4952 : : }
4953 : 6584 : else if (code == BIT_NOT_EXPR)
4954 : : {
4955 : 170 : *gsi = gsi_for_stmt (stmt);
4956 : 170 : gsi_remove (gsi, true);
4957 : 170 : release_ssa_name (lhs);
4958 : 170 : return true;
4959 : : }
4960 : : return false;
4961 : 6596 : }
4962 : :
4963 : : /* Helper of match_uaddc_usubc. Look through an integral cast
4964 : : which should preserve [0, 1] range value (unless source has
4965 : : 1-bit signed type) and the cast has single use. */
4966 : :
4967 : : static gimple *
4968 : 2009836 : uaddc_cast (gimple *g)
4969 : : {
4970 : 2009836 : if (!gimple_assign_cast_p (g))
4971 : : return g;
4972 : 477706 : tree op = gimple_assign_rhs1 (g);
4973 : 477706 : if (TREE_CODE (op) == SSA_NAME
4974 : 400894 : && INTEGRAL_TYPE_P (TREE_TYPE (op))
4975 : 281236 : && (TYPE_PRECISION (TREE_TYPE (op)) > 1
4976 : 6349 : || TYPE_UNSIGNED (TREE_TYPE (op)))
4977 : 758942 : && has_single_use (gimple_assign_lhs (g)))
4978 : 181110 : return SSA_NAME_DEF_STMT (op);
4979 : : return g;
4980 : : }
4981 : :
4982 : : /* Helper of match_uaddc_usubc. Look through a NE_EXPR
4983 : : comparison with 0 which also preserves [0, 1] value range. */
4984 : :
4985 : : static gimple *
4986 : 2009995 : uaddc_ne0 (gimple *g)
4987 : : {
4988 : 2009995 : if (is_gimple_assign (g)
4989 : 1227030 : && gimple_assign_rhs_code (g) == NE_EXPR
4990 : 55065 : && integer_zerop (gimple_assign_rhs2 (g))
4991 : 6060 : && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
4992 : 2016055 : && has_single_use (gimple_assign_lhs (g)))
4993 : 5757 : return SSA_NAME_DEF_STMT (gimple_assign_rhs1 (g));
4994 : : return g;
4995 : : }
4996 : :
4997 : : /* Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
4998 : : operand. */
4999 : :
5000 : : static bool
5001 : 2010826 : uaddc_is_cplxpart (gimple *g, tree_code part)
5002 : : {
5003 : 2010826 : return (is_gimple_assign (g)
5004 : 1225952 : && gimple_assign_rhs_code (g) == part
5005 : 2013226 : && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (g), 0)) == SSA_NAME);
5006 : : }
5007 : :
5008 : : /* Try to match e.g.
5009 : : _29 = .ADD_OVERFLOW (_3, _4);
5010 : : _30 = REALPART_EXPR <_29>;
5011 : : _31 = IMAGPART_EXPR <_29>;
5012 : : _32 = .ADD_OVERFLOW (_30, _38);
5013 : : _33 = REALPART_EXPR <_32>;
5014 : : _34 = IMAGPART_EXPR <_32>;
5015 : : _35 = _31 + _34;
5016 : : as
5017 : : _36 = .UADDC (_3, _4, _38);
5018 : : _33 = REALPART_EXPR <_36>;
5019 : : _35 = IMAGPART_EXPR <_36>;
5020 : : or
5021 : : _22 = .SUB_OVERFLOW (_6, _5);
5022 : : _23 = REALPART_EXPR <_22>;
5023 : : _24 = IMAGPART_EXPR <_22>;
5024 : : _25 = .SUB_OVERFLOW (_23, _37);
5025 : : _26 = REALPART_EXPR <_25>;
5026 : : _27 = IMAGPART_EXPR <_25>;
5027 : : _28 = _24 | _27;
5028 : : as
5029 : : _29 = .USUBC (_6, _5, _37);
5030 : : _26 = REALPART_EXPR <_29>;
5031 : : _288 = IMAGPART_EXPR <_29>;
5032 : : provided _38 or _37 above have [0, 1] range
5033 : : and _3, _4 and _30 or _6, _5 and _23 are unsigned
5034 : : integral types with the same precision. Whether + or | or ^ is
5035 : : used on the IMAGPART_EXPR results doesn't matter, with one of
5036 : : added or subtracted operands in [0, 1] range at most one
5037 : : .ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow. */
5038 : :
5039 : : static bool
5040 : 2753907 : match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
5041 : : {
5042 : 2753907 : tree rhs[4];
5043 : 2753907 : rhs[0] = gimple_assign_rhs1 (stmt);
5044 : 2753907 : rhs[1] = gimple_assign_rhs2 (stmt);
5045 : 2753907 : rhs[2] = NULL_TREE;
5046 : 2753907 : rhs[3] = NULL_TREE;
5047 : 2753907 : tree type = TREE_TYPE (rhs[0]);
5048 : 2753907 : if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))
5049 : : return false;
5050 : :
5051 : 1616517 : auto_vec<gimple *, 2> temp_stmts;
5052 : 1616517 : if (code != BIT_IOR_EXPR && code != BIT_XOR_EXPR)
5053 : : {
5054 : : /* If overflow flag is ignored on the MSB limb, we can end up with
5055 : : the most significant limb handled as r = op1 + op2 + ovf1 + ovf2;
5056 : : or r = op1 - op2 - ovf1 - ovf2; or various equivalent expressions
5057 : : thereof. Handle those like the ovf = ovf1 + ovf2; case to recognize
5058 : : the limb below the MSB, but also create another .UADDC/.USUBC call
5059 : : for the last limb.
5060 : :
5061 : : First look through assignments with the same rhs code as CODE,
5062 : : with the exception that subtraction of a constant is canonicalized
5063 : : into addition of its negation. rhs[0] will be minuend for
5064 : : subtractions and one of addends for addition, all other assigned
5065 : : rhs[i] operands will be subtrahends or other addends. */
5066 : 1486407 : while (TREE_CODE (rhs[0]) == SSA_NAME && !rhs[3])
5067 : : {
5068 : 1461279 : gimple *g = SSA_NAME_DEF_STMT (rhs[0]);
5069 : 1461279 : if (has_single_use (rhs[0])
5070 : 498151 : && is_gimple_assign (g)
5071 : 1900827 : && (gimple_assign_rhs_code (g) == code
5072 : 412565 : || (code == MINUS_EXPR
5073 : 53518 : && gimple_assign_rhs_code (g) == PLUS_EXPR
5074 : 16592 : && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST)))
5075 : : {
5076 : 39308 : tree r2 = gimple_assign_rhs2 (g);
5077 : 39308 : if (gimple_assign_rhs_code (g) != code)
5078 : : {
5079 : 12325 : r2 = const_unop (NEGATE_EXPR, TREE_TYPE (r2), r2);
5080 : 12325 : if (!r2)
5081 : : break;
5082 : : }
5083 : 39308 : rhs[0] = gimple_assign_rhs1 (g);
5084 : 39308 : tree &r = rhs[2] ? rhs[3] : rhs[2];
5085 : 39308 : r = r2;
5086 : 39308 : temp_stmts.quick_push (g);
5087 : : }
5088 : : else
5089 : : break;
5090 : : }
5091 : 4341297 : for (int i = 1; i <= 2; ++i)
5092 : 2940469 : while (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME && !rhs[3])
5093 : : {
5094 : 520359 : gimple *g = SSA_NAME_DEF_STMT (rhs[i]);
5095 : 520359 : if (has_single_use (rhs[i])
5096 : 270666 : && is_gimple_assign (g)
5097 : 772397 : && gimple_assign_rhs_code (g) == PLUS_EXPR)
5098 : : {
5099 : 46271 : rhs[i] = gimple_assign_rhs1 (g);
5100 : 46271 : if (rhs[2])
5101 : 9537 : rhs[3] = gimple_assign_rhs2 (g);
5102 : : else
5103 : 36734 : rhs[2] = gimple_assign_rhs2 (g);
5104 : 46271 : temp_stmts.quick_push (g);
5105 : : }
5106 : : else
5107 : : break;
5108 : : }
5109 : : /* If there are just 3 addends or one minuend and two subtrahends,
5110 : : check for UADDC or USUBC being pattern recognized earlier.
5111 : : Say r = op1 + op2 + ovf1 + ovf2; where the (ovf1 + ovf2) part
5112 : : got pattern matched earlier as __imag__ .UADDC (arg1, arg2, arg3)
5113 : : etc. */
5114 : 1447099 : if (rhs[2] && !rhs[3])
5115 : : {
5116 : 295483 : for (int i = (code == MINUS_EXPR ? 1 : 0); i < 3; ++i)
5117 : 171944 : if (TREE_CODE (rhs[i]) == SSA_NAME)
5118 : : {
5119 : 133940 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5120 : 133940 : im = uaddc_ne0 (im);
5121 : 133940 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5122 : : {
5123 : : /* We found one of the 3 addends or 2 subtrahends to be
5124 : : __imag__ of something, verify it is .UADDC/.USUBC. */
5125 : 215 : tree rhs1 = gimple_assign_rhs1 (im);
5126 : 215 : gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
5127 : 215 : tree ovf_lhs = NULL_TREE;
5128 : 215 : tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
5129 : 235 : if (gimple_call_internal_p (ovf, code == PLUS_EXPR
5130 : : ? IFN_ADD_OVERFLOW
5131 : : : IFN_SUB_OVERFLOW))
5132 : : {
5133 : : /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
5134 : : This is for the case of 2 chained .UADDC/.USUBC,
5135 : : where the first one uses 0 carry-in and the second
5136 : : one ignores the carry-out.
5137 : : So, something like:
5138 : : _16 = .ADD_OVERFLOW (_1, _2);
5139 : : _17 = REALPART_EXPR <_16>;
5140 : : _18 = IMAGPART_EXPR <_16>;
5141 : : _15 = _3 + _4;
5142 : : _12 = _15 + _18;
5143 : : where the first 3 statements come from the lower
5144 : : limb addition and the last 2 from the higher limb
5145 : : which ignores carry-out. */
5146 : 197 : ovf_lhs = gimple_call_lhs (ovf);
5147 : 197 : tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
5148 : 197 : ovf_arg1 = gimple_call_arg (ovf, 0);
5149 : 197 : ovf_arg2 = gimple_call_arg (ovf, 1);
5150 : : /* In that case we need to punt if the types don't
5151 : : mismatch. */
5152 : 197 : if (!types_compatible_p (type, ovf_lhs_type)
5153 : 197 : || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
5154 : 391 : || !types_compatible_p (type,
5155 : 194 : TREE_TYPE (ovf_arg2)))
5156 : : ovf_lhs = NULL_TREE;
5157 : : else
5158 : : {
5159 : 479 : for (int i = (code == PLUS_EXPR ? 1 : 0);
5160 : 479 : i >= 0; --i)
5161 : : {
5162 : 339 : tree r = gimple_call_arg (ovf, i);
5163 : 339 : if (TREE_CODE (r) != SSA_NAME)
5164 : 0 : continue;
5165 : 339 : if (uaddc_is_cplxpart (SSA_NAME_DEF_STMT (r),
5166 : : REALPART_EXPR))
5167 : : {
5168 : : /* Punt if one of the args which isn't
5169 : : subtracted isn't __real__; that could
5170 : : then prevent better match later.
5171 : : Consider:
5172 : : _3 = .ADD_OVERFLOW (_1, _2);
5173 : : _4 = REALPART_EXPR <_3>;
5174 : : _5 = IMAGPART_EXPR <_3>;
5175 : : _7 = .ADD_OVERFLOW (_4, _6);
5176 : : _8 = REALPART_EXPR <_7>;
5177 : : _9 = IMAGPART_EXPR <_7>;
5178 : : _12 = _10 + _11;
5179 : : _13 = _12 + _9;
5180 : : _14 = _13 + _5;
5181 : : We want to match this when called on
5182 : : the last stmt as a pair of .UADDC calls,
5183 : : but without this check we could turn
5184 : : that prematurely on _13 = _12 + _9;
5185 : : stmt into .UADDC with 0 carry-in just
5186 : : on the second .ADD_OVERFLOW call and
5187 : : another replacing the _12 and _13
5188 : : additions. */
5189 : : ovf_lhs = NULL_TREE;
5190 : : break;
5191 : : }
5192 : : }
5193 : : }
5194 : 190 : if (ovf_lhs)
5195 : : {
5196 : 140 : use_operand_p use_p;
5197 : 140 : imm_use_iterator iter;
5198 : 140 : tree re_lhs = NULL_TREE;
5199 : 420 : FOR_EACH_IMM_USE_FAST (use_p, iter, ovf_lhs)
5200 : : {
5201 : 280 : gimple *use_stmt = USE_STMT (use_p);
5202 : 280 : if (is_gimple_debug (use_stmt))
5203 : 0 : continue;
5204 : 280 : if (use_stmt == im)
5205 : 140 : continue;
5206 : 140 : if (!uaddc_is_cplxpart (use_stmt,
5207 : : REALPART_EXPR))
5208 : : {
5209 : : ovf_lhs = NULL_TREE;
5210 : : break;
5211 : : }
5212 : 140 : re_lhs = gimple_assign_lhs (use_stmt);
5213 : : }
5214 : 140 : if (ovf_lhs && re_lhs)
5215 : : {
5216 : 362 : FOR_EACH_IMM_USE_FAST (use_p, iter, re_lhs)
5217 : : {
5218 : 281 : gimple *use_stmt = USE_STMT (use_p);
5219 : 281 : if (is_gimple_debug (use_stmt))
5220 : 103 : continue;
5221 : 178 : internal_fn ifn
5222 : 178 : = gimple_call_internal_fn (ovf);
5223 : : /* Punt if the __real__ of lhs is used
5224 : : in the same .*_OVERFLOW call.
5225 : : Consider:
5226 : : _3 = .ADD_OVERFLOW (_1, _2);
5227 : : _4 = REALPART_EXPR <_3>;
5228 : : _5 = IMAGPART_EXPR <_3>;
5229 : : _7 = .ADD_OVERFLOW (_4, _6);
5230 : : _8 = REALPART_EXPR <_7>;
5231 : : _9 = IMAGPART_EXPR <_7>;
5232 : : _12 = _10 + _11;
5233 : : _13 = _12 + _5;
5234 : : _14 = _13 + _9;
5235 : : We want to match this when called on
5236 : : the last stmt as a pair of .UADDC calls,
5237 : : but without this check we could turn
5238 : : that prematurely on _13 = _12 + _5;
5239 : : stmt into .UADDC with 0 carry-in just
5240 : : on the first .ADD_OVERFLOW call and
5241 : : another replacing the _12 and _13
5242 : : additions. */
5243 : 178 : if (gimple_call_internal_p (use_stmt, ifn))
5244 : : {
5245 : : ovf_lhs = NULL_TREE;
5246 : : break;
5247 : : }
5248 : : }
5249 : : }
5250 : : }
5251 : : }
5252 : 140 : if ((ovf_lhs
5253 : 143 : || gimple_call_internal_p (ovf,
5254 : : code == PLUS_EXPR
5255 : : ? IFN_UADDC : IFN_USUBC))
5256 : 241 : && (optab_handler (code == PLUS_EXPR
5257 : : ? uaddc5_optab : usubc5_optab,
5258 : 87 : TYPE_MODE (type))
5259 : : != CODE_FOR_nothing))
5260 : : {
5261 : : /* And in that case build another .UADDC/.USUBC
5262 : : call for the most significand limb addition.
5263 : : Overflow bit is ignored here. */
5264 : 63 : if (i != 2)
5265 : 63 : std::swap (rhs[i], rhs[2]);
5266 : 63 : gimple *g
5267 : 77 : = gimple_build_call_internal (code == PLUS_EXPR
5268 : : ? IFN_UADDC
5269 : : : IFN_USUBC,
5270 : : 3, rhs[0], rhs[1],
5271 : : rhs[2]);
5272 : 63 : tree nlhs = make_ssa_name (build_complex_type (type));
5273 : 63 : gimple_call_set_lhs (g, nlhs);
5274 : 63 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5275 : 63 : tree ilhs = gimple_assign_lhs (stmt);
5276 : 63 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5277 : : build1 (REALPART_EXPR,
5278 : 63 : TREE_TYPE (ilhs),
5279 : : nlhs));
5280 : 63 : gsi_replace (gsi, g, true);
5281 : : /* And if it is initialized from result of __imag__
5282 : : of .{ADD,SUB}_OVERFLOW call, replace that
5283 : : call with .U{ADD,SUB}C call with the same arguments,
5284 : : just 0 added as third argument. This isn't strictly
5285 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5286 : : produce the same result, but may result in better
5287 : : generated code on some targets where the backend can
5288 : : better prepare in how the result will be used. */
5289 : 63 : if (ovf_lhs)
5290 : : {
5291 : 57 : tree zero = build_zero_cst (type);
5292 : 57 : g = gimple_build_call_internal (code == PLUS_EXPR
5293 : : ? IFN_UADDC
5294 : : : IFN_USUBC,
5295 : : 3, ovf_arg1,
5296 : : ovf_arg2, zero);
5297 : 57 : gimple_call_set_lhs (g, ovf_lhs);
5298 : 57 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf);
5299 : 57 : gsi_replace (&gsi2, g, true);
5300 : : }
5301 : 63 : return true;
5302 : : }
5303 : : }
5304 : : }
5305 : : return false;
5306 : : }
5307 : 1385298 : if (code == MINUS_EXPR && !rhs[2])
5308 : : return false;
5309 : 289 : if (code == MINUS_EXPR)
5310 : : /* Code below expects rhs[0] and rhs[1] to have the IMAGPART_EXPRs.
5311 : : So, for MINUS_EXPR swap the single added rhs operand (others are
5312 : : subtracted) to rhs[3]. */
5313 : 289 : std::swap (rhs[0], rhs[3]);
5314 : : }
5315 : : /* Walk from both operands of STMT (for +/- even sometimes from
5316 : : all the 4 addends or 3 subtrahends), see through casts and != 0
5317 : : statements which would preserve [0, 1] range of values and
5318 : : check which is initialized from __imag__. */
5319 : 7182406 : gimple *im1 = NULL, *im2 = NULL;
5320 : 14363658 : for (int i = 0; i < (code == MINUS_EXPR ? 3 : 4); i++)
5321 : 5746030 : if (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME)
5322 : : {
5323 : 1875804 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5324 : 1875804 : im = uaddc_ne0 (im);
5325 : 1875804 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5326 : : {
5327 : 1667 : if (im1 == NULL)
5328 : : {
5329 : 1275 : im1 = im;
5330 : 1275 : if (i != 0)
5331 : 369 : std::swap (rhs[0], rhs[i]);
5332 : : }
5333 : : else
5334 : : {
5335 : 392 : im2 = im;
5336 : 392 : if (i != 1)
5337 : 23 : std::swap (rhs[1], rhs[i]);
5338 : : break;
5339 : : }
5340 : : }
5341 : : }
5342 : : /* If we don't find at least two, punt. */
5343 : 1436768 : if (!im2)
5344 : : return false;
5345 : : /* Check they are __imag__ of .ADD_OVERFLOW or .SUB_OVERFLOW call results,
5346 : : either both .ADD_OVERFLOW or both .SUB_OVERFLOW and that we have
5347 : : uaddc5/usubc5 named pattern for the corresponding mode. */
5348 : 392 : gimple *ovf1
5349 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im1), 0));
5350 : 392 : gimple *ovf2
5351 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im2), 0));
5352 : 392 : internal_fn ifn;
5353 : 392 : if (!is_gimple_call (ovf1)
5354 : 392 : || !gimple_call_internal_p (ovf1)
5355 : 392 : || ((ifn = gimple_call_internal_fn (ovf1)) != IFN_ADD_OVERFLOW
5356 : 59 : && ifn != IFN_SUB_OVERFLOW)
5357 : 369 : || !gimple_call_internal_p (ovf2, ifn)
5358 : 397 : || optab_handler (ifn == IFN_ADD_OVERFLOW ? uaddc5_optab : usubc5_optab,
5359 : 365 : TYPE_MODE (type)) == CODE_FOR_nothing
5360 : 485 : || (rhs[2]
5361 : 17 : && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
5362 : 15 : TYPE_MODE (type)) == CODE_FOR_nothing))
5363 : 299 : return false;
5364 : 93 : tree arg1, arg2, arg3 = NULL_TREE;
5365 : 93 : gimple *re1 = NULL, *re2 = NULL;
5366 : : /* On one of the two calls, one of the .ADD_OVERFLOW/.SUB_OVERFLOW arguments
5367 : : should be initialized from __real__ of the other of the two calls.
5368 : : Though, for .SUB_OVERFLOW, it has to be the first argument, not the
5369 : : second one. */
5370 : 340 : for (int i = (ifn == IFN_ADD_OVERFLOW ? 1 : 0); i >= 0; --i)
5371 : 349 : for (gimple *ovf = ovf1; ovf; ovf = (ovf == ovf1 ? ovf2 : NULL))
5372 : : {
5373 : 288 : tree arg = gimple_call_arg (ovf, i);
5374 : 288 : if (TREE_CODE (arg) != SSA_NAME)
5375 : 2 : continue;
5376 : 286 : re1 = SSA_NAME_DEF_STMT (arg);
5377 : 286 : if (uaddc_is_cplxpart (re1, REALPART_EXPR)
5378 : 379 : && (SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (re1), 0))
5379 : 93 : == (ovf == ovf1 ? ovf2 : ovf1)))
5380 : : {
5381 : 93 : if (ovf == ovf1)
5382 : : {
5383 : : /* Make sure ovf2 is the .*_OVERFLOW call with argument
5384 : : initialized from __real__ of ovf1. */
5385 : 20 : std::swap (rhs[0], rhs[1]);
5386 : 20 : std::swap (im1, im2);
5387 : 20 : std::swap (ovf1, ovf2);
5388 : : }
5389 : 93 : arg3 = gimple_call_arg (ovf, 1 - i);
5390 : 93 : i = -1;
5391 : 93 : break;
5392 : : }
5393 : : }
5394 : 93 : if (!arg3)
5395 : : return false;
5396 : 93 : arg1 = gimple_call_arg (ovf1, 0);
5397 : 93 : arg2 = gimple_call_arg (ovf1, 1);
5398 : 93 : if (!types_compatible_p (type, TREE_TYPE (arg1)))
5399 : : return false;
5400 : 93 : int kind[2] = { 0, 0 };
5401 : 93 : tree arg_im[2] = { NULL_TREE, NULL_TREE };
5402 : : /* At least one of arg2 and arg3 should have type compatible
5403 : : with arg1/rhs[0], and the other one should have value in [0, 1]
5404 : : range. If both are in [0, 1] range and type compatible with
5405 : : arg1/rhs[0], try harder to find after looking through casts,
5406 : : != 0 comparisons which one is initialized to __imag__ of
5407 : : .{ADD,SUB}_OVERFLOW or .U{ADD,SUB}C call results. */
5408 : 279 : for (int i = 0; i < 2; ++i)
5409 : : {
5410 : 186 : tree arg = i == 0 ? arg2 : arg3;
5411 : 186 : if (types_compatible_p (type, TREE_TYPE (arg)))
5412 : 161 : kind[i] = 1;
5413 : 372 : if (!INTEGRAL_TYPE_P (TREE_TYPE (arg))
5414 : 372 : || (TYPE_PRECISION (TREE_TYPE (arg)) == 1
5415 : 25 : && !TYPE_UNSIGNED (TREE_TYPE (arg))))
5416 : 0 : continue;
5417 : 186 : if (tree_zero_one_valued_p (arg))
5418 : 51 : kind[i] |= 2;
5419 : 186 : if (TREE_CODE (arg) == SSA_NAME)
5420 : : {
5421 : 184 : gimple *g = SSA_NAME_DEF_STMT (arg);
5422 : 184 : if (gimple_assign_cast_p (g))
5423 : : {
5424 : 30 : tree op = gimple_assign_rhs1 (g);
5425 : 30 : if (TREE_CODE (op) == SSA_NAME
5426 : 30 : && INTEGRAL_TYPE_P (TREE_TYPE (op)))
5427 : 30 : g = SSA_NAME_DEF_STMT (op);
5428 : : }
5429 : 184 : g = uaddc_ne0 (g);
5430 : 184 : if (!uaddc_is_cplxpart (g, IMAGPART_EXPR))
5431 : 124 : continue;
5432 : 60 : arg_im[i] = gimple_assign_lhs (g);
5433 : 60 : g = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (g), 0));
5434 : 60 : if (!is_gimple_call (g) || !gimple_call_internal_p (g))
5435 : 0 : continue;
5436 : 60 : switch (gimple_call_internal_fn (g))
5437 : : {
5438 : 60 : case IFN_ADD_OVERFLOW:
5439 : 60 : case IFN_SUB_OVERFLOW:
5440 : 60 : case IFN_UADDC:
5441 : 60 : case IFN_USUBC:
5442 : 60 : break;
5443 : 0 : default:
5444 : 0 : continue;
5445 : : }
5446 : 60 : kind[i] |= 4;
5447 : : }
5448 : : }
5449 : : /* Make arg2 the one with compatible type and arg3 the one
5450 : : with [0, 1] range. If both is true for both operands,
5451 : : prefer as arg3 result of __imag__ of some ifn. */
5452 : 93 : if ((kind[0] & 1) == 0 || ((kind[1] & 1) != 0 && kind[0] > kind[1]))
5453 : : {
5454 : 1 : std::swap (arg2, arg3);
5455 : 1 : std::swap (kind[0], kind[1]);
5456 : 1 : std::swap (arg_im[0], arg_im[1]);
5457 : : }
5458 : 93 : if ((kind[0] & 1) == 0 || (kind[1] & 6) == 0)
5459 : : return false;
5460 : 69 : if (!has_single_use (gimple_assign_lhs (im1))
5461 : 67 : || !has_single_use (gimple_assign_lhs (im2))
5462 : 67 : || !has_single_use (gimple_assign_lhs (re1))
5463 : 136 : || num_imm_uses (gimple_call_lhs (ovf1)) != 2)
5464 : : return false;
5465 : : /* Check that ovf2's result is used in __real__ and set re2
5466 : : to that statement. */
5467 : 67 : use_operand_p use_p;
5468 : 67 : imm_use_iterator iter;
5469 : 67 : tree lhs = gimple_call_lhs (ovf2);
5470 : 200 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
5471 : : {
5472 : 133 : gimple *use_stmt = USE_STMT (use_p);
5473 : 133 : if (is_gimple_debug (use_stmt))
5474 : 0 : continue;
5475 : 133 : if (use_stmt == im2)
5476 : 67 : continue;
5477 : 66 : if (re2)
5478 : : return false;
5479 : 66 : if (!uaddc_is_cplxpart (use_stmt, REALPART_EXPR))
5480 : : return false;
5481 : : re2 = use_stmt;
5482 : : }
5483 : : /* Build .UADDC/.USUBC call which will be placed before the stmt. */
5484 : 67 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf2);
5485 : 67 : gimple *g;
5486 : 67 : if ((kind[1] & 4) != 0 && types_compatible_p (type, TREE_TYPE (arg_im[1])))
5487 : : arg3 = arg_im[1];
5488 : 67 : if ((kind[1] & 1) == 0)
5489 : : {
5490 : 25 : if (TREE_CODE (arg3) == INTEGER_CST)
5491 : 0 : arg3 = fold_convert (type, arg3);
5492 : : else
5493 : : {
5494 : 25 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, arg3);
5495 : 25 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5496 : 25 : arg3 = gimple_assign_lhs (g);
5497 : : }
5498 : : }
5499 : 89 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5500 : : ? IFN_UADDC : IFN_USUBC,
5501 : : 3, arg1, arg2, arg3);
5502 : 67 : tree nlhs = make_ssa_name (TREE_TYPE (lhs));
5503 : 67 : gimple_call_set_lhs (g, nlhs);
5504 : 67 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5505 : : /* In the case where stmt is | or ^ of two overflow flags
5506 : : or addition of those, replace stmt with __imag__ of the above
5507 : : added call. In case of arg1 + arg2 + (ovf1 + ovf2) or
5508 : : arg1 - arg2 - (ovf1 + ovf2) just emit it before stmt. */
5509 : 67 : tree ilhs = rhs[2] ? make_ssa_name (type) : gimple_assign_lhs (stmt);
5510 : 67 : g = gimple_build_assign (ilhs, IMAGPART_EXPR,
5511 : 67 : build1 (IMAGPART_EXPR, TREE_TYPE (ilhs), nlhs));
5512 : 67 : if (rhs[2])
5513 : : {
5514 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5515 : : /* Remove some further statements which can't be kept in the IL because
5516 : : they can use SSA_NAMEs whose setter is going to be removed too. */
5517 : 75 : for (gimple *g2 : temp_stmts)
5518 : : {
5519 : 30 : gsi2 = gsi_for_stmt (g2);
5520 : 30 : gsi_remove (&gsi2, true);
5521 : 30 : release_defs (g2);
5522 : : }
5523 : : }
5524 : : else
5525 : 52 : gsi_replace (gsi, g, true);
5526 : : /* Remove some statements which can't be kept in the IL because they
5527 : : use SSA_NAME whose setter is going to be removed too. */
5528 : 67 : tree rhs1 = rhs[1];
5529 : 103 : for (int i = 0; i < 2; i++)
5530 : 85 : if (rhs1 == gimple_assign_lhs (im2))
5531 : : break;
5532 : : else
5533 : : {
5534 : 36 : g = SSA_NAME_DEF_STMT (rhs1);
5535 : 36 : rhs1 = gimple_assign_rhs1 (g);
5536 : 36 : gsi2 = gsi_for_stmt (g);
5537 : 36 : gsi_remove (&gsi2, true);
5538 : 36 : release_defs (g);
5539 : : }
5540 : 67 : gcc_checking_assert (rhs1 == gimple_assign_lhs (im2));
5541 : 67 : gsi2 = gsi_for_stmt (im2);
5542 : 67 : gsi_remove (&gsi2, true);
5543 : 67 : release_defs (im2);
5544 : : /* Replace the re2 statement with __real__ of the newly added
5545 : : .UADDC/.USUBC call. */
5546 : 67 : if (re2)
5547 : : {
5548 : 66 : gsi2 = gsi_for_stmt (re2);
5549 : 66 : tree rlhs = gimple_assign_lhs (re2);
5550 : 66 : g = gimple_build_assign (rlhs, REALPART_EXPR,
5551 : 66 : build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
5552 : 66 : gsi_replace (&gsi2, g, true);
5553 : : }
5554 : 67 : if (rhs[2])
5555 : : {
5556 : : /* If this is the arg1 + arg2 + (ovf1 + ovf2) or
5557 : : arg1 - arg2 - (ovf1 + ovf2) case for the most significant limb,
5558 : : replace stmt with __real__ of another .UADDC/.USUBC call which
5559 : : handles the most significant limb. Overflow flag from this is
5560 : : ignored. */
5561 : 17 : g = gimple_build_call_internal (code == PLUS_EXPR
5562 : : ? IFN_UADDC : IFN_USUBC,
5563 : : 3, rhs[3], rhs[2], ilhs);
5564 : 15 : nlhs = make_ssa_name (TREE_TYPE (lhs));
5565 : 15 : gimple_call_set_lhs (g, nlhs);
5566 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5567 : 15 : ilhs = gimple_assign_lhs (stmt);
5568 : 15 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5569 : 15 : build1 (REALPART_EXPR, TREE_TYPE (ilhs), nlhs));
5570 : 15 : gsi_replace (gsi, g, true);
5571 : : }
5572 : 67 : if (TREE_CODE (arg3) == SSA_NAME)
5573 : : {
5574 : : /* When pattern recognizing the second least significant limb
5575 : : above (i.e. first pair of .{ADD,SUB}_OVERFLOW calls for one limb),
5576 : : check if the [0, 1] range argument (i.e. carry in) isn't the
5577 : : result of another .{ADD,SUB}_OVERFLOW call (one handling the
5578 : : least significant limb). Again look through casts and != 0. */
5579 : 67 : gimple *im3 = SSA_NAME_DEF_STMT (arg3);
5580 : 92 : for (int i = 0; i < 2; ++i)
5581 : : {
5582 : 92 : gimple *im4 = uaddc_cast (im3);
5583 : 92 : if (im4 == im3)
5584 : : break;
5585 : : else
5586 : 25 : im3 = im4;
5587 : : }
5588 : 67 : im3 = uaddc_ne0 (im3);
5589 : 67 : if (uaddc_is_cplxpart (im3, IMAGPART_EXPR))
5590 : : {
5591 : 60 : gimple *ovf3
5592 : 60 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
5593 : 60 : if (gimple_call_internal_p (ovf3, ifn))
5594 : : {
5595 : 25 : lhs = gimple_call_lhs (ovf3);
5596 : 25 : arg1 = gimple_call_arg (ovf3, 0);
5597 : 25 : arg2 = gimple_call_arg (ovf3, 1);
5598 : 25 : if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
5599 : 25 : && types_compatible_p (type, TREE_TYPE (arg1))
5600 : 50 : && types_compatible_p (type, TREE_TYPE (arg2)))
5601 : : {
5602 : : /* And if it is initialized from result of __imag__
5603 : : of .{ADD,SUB}_OVERFLOW call, replace that
5604 : : call with .U{ADD,SUB}C call with the same arguments,
5605 : : just 0 added as third argument. This isn't strictly
5606 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5607 : : produce the same result, but may result in better
5608 : : generated code on some targets where the backend can
5609 : : better prepare in how the result will be used. */
5610 : 25 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5611 : : ? IFN_UADDC : IFN_USUBC,
5612 : : 3, arg1, arg2,
5613 : : build_zero_cst (type));
5614 : 25 : gimple_call_set_lhs (g, lhs);
5615 : 25 : gsi2 = gsi_for_stmt (ovf3);
5616 : 25 : gsi_replace (&gsi2, g, true);
5617 : : }
5618 : : }
5619 : : }
5620 : : }
5621 : : return true;
5622 : 1616517 : }
5623 : :
5624 : : /* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
5625 : : (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
5626 : : isn't a direct optab. Also handle `<=`/`>` to be
5627 : : `x & (x - 1) !=/== x`. */
5628 : :
5629 : : static void
5630 : 4474184 : match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
5631 : : {
5632 : 4474184 : tree clhs, crhs;
5633 : 4474184 : enum tree_code code;
5634 : 4474184 : bool was_le = false;
5635 : 4474184 : if (gimple_code (stmt) == GIMPLE_COND)
5636 : : {
5637 : 4171212 : clhs = gimple_cond_lhs (stmt);
5638 : 4171212 : crhs = gimple_cond_rhs (stmt);
5639 : 4171212 : code = gimple_cond_code (stmt);
5640 : : }
5641 : : else
5642 : : {
5643 : 302972 : clhs = gimple_assign_rhs1 (stmt);
5644 : 302972 : crhs = gimple_assign_rhs2 (stmt);
5645 : 302972 : code = gimple_assign_rhs_code (stmt);
5646 : : }
5647 : 4474184 : if (code != LE_EXPR && code != GT_EXPR
5648 : 4474184 : && code != EQ_EXPR && code != NE_EXPR)
5649 : 4474178 : return;
5650 : 2091883 : if (code == LE_EXPR || code == GT_EXPR)
5651 : 4214786 : was_le = true;
5652 : 4214786 : if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
5653 : 4056159 : return;
5654 : 158627 : gimple *call = SSA_NAME_DEF_STMT (clhs);
5655 : 158627 : combined_fn cfn = gimple_call_combined_fn (call);
5656 : 158627 : switch (cfn)
5657 : : {
5658 : 15 : CASE_CFN_POPCOUNT:
5659 : 15 : break;
5660 : : default:
5661 : : return;
5662 : : }
5663 : 15 : if (!has_single_use (clhs))
5664 : : return;
5665 : 14 : tree arg = gimple_call_arg (call, 0);
5666 : 14 : tree type = TREE_TYPE (arg);
5667 : 14 : if (!INTEGRAL_TYPE_P (type))
5668 : : return;
5669 : 14 : bool nonzero_arg = tree_expr_nonzero_p (arg);
5670 : 14 : if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
5671 : : {
5672 : : /* Tell expand_POPCOUNT the popcount result is only used in equality
5673 : : comparison with one, so that it can decide based on rtx costs. */
5674 : 16 : gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
5675 : : was_le ? integer_minus_one_node
5676 : 8 : : (nonzero_arg ? integer_zero_node
5677 : : : integer_one_node));
5678 : 8 : gimple_call_set_lhs (g, gimple_call_lhs (call));
5679 : 8 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5680 : 8 : gsi_replace (&gsi2, g, true);
5681 : 8 : return;
5682 : : }
5683 : 6 : tree argm1 = make_ssa_name (type);
5684 : 6 : gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
5685 : : build_int_cst (type, -1));
5686 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5687 : 6 : g = gimple_build_assign (make_ssa_name (type),
5688 : 6 : (nonzero_arg || was_le) ? BIT_AND_EXPR : BIT_XOR_EXPR,
5689 : : arg, argm1);
5690 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5691 : 6 : tree_code cmpcode;
5692 : 6 : if (was_le)
5693 : : {
5694 : 0 : argm1 = build_zero_cst (type);
5695 : 0 : cmpcode = code == LE_EXPR ? EQ_EXPR : NE_EXPR;
5696 : : }
5697 : 6 : else if (nonzero_arg)
5698 : : {
5699 : 2 : argm1 = build_zero_cst (type);
5700 : 2 : cmpcode = code;
5701 : : }
5702 : : else
5703 : 4 : cmpcode = code == EQ_EXPR ? GT_EXPR : LE_EXPR;
5704 : 6 : if (gcond *cond = dyn_cast <gcond *> (stmt))
5705 : : {
5706 : 2 : gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
5707 : 2 : gimple_cond_set_rhs (cond, argm1);
5708 : 2 : gimple_cond_set_code (cond, cmpcode);
5709 : : }
5710 : : else
5711 : : {
5712 : 4 : gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
5713 : 4 : gimple_assign_set_rhs2 (stmt, argm1);
5714 : 4 : gimple_assign_set_rhs_code (stmt, cmpcode);
5715 : : }
5716 : 6 : update_stmt (stmt);
5717 : 6 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5718 : 6 : gsi_remove (&gsi2, true);
5719 : 6 : release_defs (call);
5720 : : }
5721 : :
5722 : : /* Return true if target has support for divmod. */
5723 : :
5724 : : static bool
5725 : 28484 : target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
5726 : : {
5727 : : /* If target supports hardware divmod insn, use it for divmod. */
5728 : 28484 : if (optab_handler (divmod_optab, mode) != CODE_FOR_nothing)
5729 : : return true;
5730 : :
5731 : : /* Check if libfunc for divmod is available. */
5732 : 2684 : rtx libfunc = optab_libfunc (divmod_optab, mode);
5733 : 2684 : if (libfunc != NULL_RTX)
5734 : : {
5735 : : /* If optab_handler exists for div_optab, perhaps in a wider mode,
5736 : : we don't want to use the libfunc even if it exists for given mode. */
5737 : : machine_mode div_mode;
5738 : 11166 : FOR_EACH_MODE_FROM (div_mode, mode)
5739 : 8482 : if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
5740 : : return false;
5741 : :
5742 : 2684 : return targetm.expand_divmod_libfunc != NULL;
5743 : : }
5744 : :
5745 : : return false;
5746 : : }
5747 : :
5748 : : /* Check if stmt is candidate for divmod transform. */
5749 : :
5750 : : static bool
5751 : 49288 : divmod_candidate_p (gassign *stmt)
5752 : : {
5753 : 49288 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
5754 : 49288 : machine_mode mode = TYPE_MODE (type);
5755 : 49288 : optab divmod_optab, div_optab;
5756 : :
5757 : 49288 : if (TYPE_UNSIGNED (type))
5758 : : {
5759 : : divmod_optab = udivmod_optab;
5760 : : div_optab = udiv_optab;
5761 : : }
5762 : : else
5763 : : {
5764 : 20641 : divmod_optab = sdivmod_optab;
5765 : 20641 : div_optab = sdiv_optab;
5766 : : }
5767 : :
5768 : 49288 : tree op1 = gimple_assign_rhs1 (stmt);
5769 : 49288 : tree op2 = gimple_assign_rhs2 (stmt);
5770 : :
5771 : : /* Disable the transform if either is a constant, since division-by-constant
5772 : : may have specialized expansion. */
5773 : 49288 : if (CONSTANT_CLASS_P (op1))
5774 : : return false;
5775 : :
5776 : 45586 : if (CONSTANT_CLASS_P (op2))
5777 : : {
5778 : 19436 : if (integer_pow2p (op2))
5779 : : return false;
5780 : :
5781 : 16979 : if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
5782 : 18058 : && element_precision (type) <= BITS_PER_WORD)
5783 : : return false;
5784 : :
5785 : : /* If the divisor is not power of 2 and the precision wider than
5786 : : HWI, expand_divmod punts on that, so in that case it is better
5787 : : to use divmod optab or libfunc. Similarly if choose_multiplier
5788 : : might need pre/post shifts of BITS_PER_WORD or more. */
5789 : : }
5790 : :
5791 : : /* Exclude the case where TYPE_OVERFLOW_TRAPS (type) as that should
5792 : : expand using the [su]divv optabs. */
5793 : 28484 : if (TYPE_OVERFLOW_TRAPS (type))
5794 : : return false;
5795 : :
5796 : 28484 : if (!target_supports_divmod_p (divmod_optab, div_optab, mode))
5797 : : return false;
5798 : :
5799 : : return true;
5800 : : }
5801 : :
5802 : : /* This function looks for:
5803 : : t1 = a TRUNC_DIV_EXPR b;
5804 : : t2 = a TRUNC_MOD_EXPR b;
5805 : : and transforms it to the following sequence:
5806 : : complex_tmp = DIVMOD (a, b);
5807 : : t1 = REALPART_EXPR(a);
5808 : : t2 = IMAGPART_EXPR(b);
5809 : : For conditions enabling the transform see divmod_candidate_p().
5810 : :
5811 : : The pass has three parts:
5812 : : 1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
5813 : : other trunc_div_expr and trunc_mod_expr stmts.
5814 : : 2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
5815 : : to stmts vector.
5816 : : 3) Insert DIVMOD call just before top_stmt and update entries in
5817 : : stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
5818 : : IMAGPART_EXPR for mod). */
5819 : :
5820 : : static bool
5821 : 49311 : convert_to_divmod (gassign *stmt)
5822 : : {
5823 : 49311 : if (stmt_can_throw_internal (cfun, stmt)
5824 : 49311 : || !divmod_candidate_p (stmt))
5825 : 20827 : return false;
5826 : :
5827 : 28484 : tree op1 = gimple_assign_rhs1 (stmt);
5828 : 28484 : tree op2 = gimple_assign_rhs2 (stmt);
5829 : :
5830 : 28484 : imm_use_iterator use_iter;
5831 : 28484 : gimple *use_stmt;
5832 : 28484 : auto_vec<gimple *> stmts;
5833 : :
5834 : 28484 : gimple *top_stmt = stmt;
5835 : 28484 : basic_block top_bb = gimple_bb (stmt);
5836 : :
5837 : : /* Part 1: Try to set top_stmt to "topmost" stmt that dominates
5838 : : at-least stmt and possibly other trunc_div/trunc_mod stmts
5839 : : having same operands as stmt. */
5840 : :
5841 : 120142 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op1)
5842 : : {
5843 : 91658 : if (is_gimple_assign (use_stmt)
5844 : 56384 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5845 : 44460 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5846 : 46784 : && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0)
5847 : 138325 : && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0))
5848 : : {
5849 : 40326 : if (stmt_can_throw_internal (cfun, use_stmt))
5850 : 0 : continue;
5851 : :
5852 : 40326 : basic_block bb = gimple_bb (use_stmt);
5853 : :
5854 : 40326 : if (bb == top_bb)
5855 : : {
5856 : 39574 : if (gimple_uid (use_stmt) < gimple_uid (top_stmt))
5857 : 5203 : top_stmt = use_stmt;
5858 : : }
5859 : 752 : else if (dominated_by_p (CDI_DOMINATORS, top_bb, bb))
5860 : : {
5861 : 207 : top_bb = bb;
5862 : 207 : top_stmt = use_stmt;
5863 : : }
5864 : : }
5865 : 28484 : }
5866 : :
5867 : 28484 : tree top_op1 = gimple_assign_rhs1 (top_stmt);
5868 : 28484 : tree top_op2 = gimple_assign_rhs2 (top_stmt);
5869 : :
5870 : 28484 : stmts.safe_push (top_stmt);
5871 : 28484 : bool div_seen = (gimple_assign_rhs_code (top_stmt) == TRUNC_DIV_EXPR);
5872 : :
5873 : : /* Part 2: Add all trunc_div/trunc_mod statements domianted by top_bb
5874 : : to stmts vector. The 2nd loop will always add stmt to stmts vector, since
5875 : : gimple_bb (top_stmt) dominates gimple_bb (stmt), so the
5876 : : 2nd loop ends up adding at-least single trunc_mod_expr stmt. */
5877 : :
5878 : 120142 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, top_op1)
5879 : : {
5880 : 91658 : if (is_gimple_assign (use_stmt)
5881 : 56384 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5882 : 44460 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5883 : 46784 : && operand_equal_p (top_op1, gimple_assign_rhs1 (use_stmt), 0)
5884 : 138325 : && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0))
5885 : : {
5886 : 68906 : if (use_stmt == top_stmt
5887 : 11842 : || stmt_can_throw_internal (cfun, use_stmt)
5888 : 52168 : || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb))
5889 : 28580 : continue;
5890 : :
5891 : 11746 : stmts.safe_push (use_stmt);
5892 : 11746 : if (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR)
5893 : 91658 : div_seen = true;
5894 : : }
5895 : 28484 : }
5896 : :
5897 : 28484 : if (!div_seen)
5898 : : return false;
5899 : :
5900 : : /* Part 3: Create libcall to internal fn DIVMOD:
5901 : : divmod_tmp = DIVMOD (op1, op2). */
5902 : :
5903 : 11720 : gcall *call_stmt = gimple_build_call_internal (IFN_DIVMOD, 2, op1, op2);
5904 : 11720 : tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
5905 : : call_stmt, "divmod_tmp");
5906 : 11720 : gimple_call_set_lhs (call_stmt, res);
5907 : : /* We rejected throwing statements above. */
5908 : 11720 : gimple_call_set_nothrow (call_stmt, true);
5909 : :
5910 : : /* Insert the call before top_stmt. */
5911 : 11720 : gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
5912 : 11720 : gsi_insert_before (&top_stmt_gsi, call_stmt, GSI_SAME_STMT);
5913 : :
5914 : 11720 : widen_mul_stats.divmod_calls_inserted++;
5915 : :
5916 : : /* Update all statements in stmts vector:
5917 : : lhs = op1 TRUNC_DIV_EXPR op2 -> lhs = REALPART_EXPR<divmod_tmp>
5918 : : lhs = op1 TRUNC_MOD_EXPR op2 -> lhs = IMAGPART_EXPR<divmod_tmp>. */
5919 : :
5920 : 63668 : for (unsigned i = 0; stmts.iterate (i, &use_stmt); ++i)
5921 : : {
5922 : 23464 : tree new_rhs;
5923 : :
5924 : 23464 : switch (gimple_assign_rhs_code (use_stmt))
5925 : : {
5926 : 11730 : case TRUNC_DIV_EXPR:
5927 : 11730 : new_rhs = fold_build1 (REALPART_EXPR, TREE_TYPE (op1), res);
5928 : 11730 : break;
5929 : :
5930 : 11734 : case TRUNC_MOD_EXPR:
5931 : 11734 : new_rhs = fold_build1 (IMAGPART_EXPR, TREE_TYPE (op1), res);
5932 : 11734 : break;
5933 : :
5934 : 0 : default:
5935 : 0 : gcc_unreachable ();
5936 : : }
5937 : :
5938 : 23464 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
5939 : 23464 : gimple_assign_set_rhs_from_tree (&gsi, new_rhs);
5940 : 23464 : update_stmt (use_stmt);
5941 : : }
5942 : :
5943 : : return true;
5944 : 28484 : }
5945 : :
5946 : : /* Process a single gimple assignment STMT, which has a RSHIFT_EXPR as
5947 : : its rhs, and try to convert it into a MULT_HIGHPART_EXPR. The return
5948 : : value is true iff we converted the statement. */
5949 : :
5950 : : static bool
5951 : 171279 : convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
5952 : : {
5953 : 171279 : tree lhs = gimple_assign_lhs (stmt);
5954 : 171279 : tree stype = TREE_TYPE (lhs);
5955 : 171279 : tree sarg0 = gimple_assign_rhs1 (stmt);
5956 : 171279 : tree sarg1 = gimple_assign_rhs2 (stmt);
5957 : :
5958 : 171279 : if (TREE_CODE (stype) != INTEGER_TYPE
5959 : 164637 : || TREE_CODE (sarg1) != INTEGER_CST
5960 : 149145 : || TREE_CODE (sarg0) != SSA_NAME
5961 : 149144 : || !tree_fits_uhwi_p (sarg1)
5962 : 320423 : || !has_single_use (sarg0))
5963 : : return false;
5964 : :
5965 : 39907 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (sarg0));
5966 : 37034 : if (!def)
5967 : : return false;
5968 : :
5969 : 37034 : enum tree_code mcode = gimple_assign_rhs_code (def);
5970 : 37034 : if (mcode == NOP_EXPR)
5971 : : {
5972 : 5641 : tree tmp = gimple_assign_rhs1 (def);
5973 : 5641 : if (TREE_CODE (tmp) != SSA_NAME || !has_single_use (tmp))
5974 : : return false;
5975 : 172030 : def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (tmp));
5976 : 1593 : if (!def)
5977 : : return false;
5978 : 1593 : mcode = gimple_assign_rhs_code (def);
5979 : : }
5980 : :
5981 : 32986 : if (mcode != WIDEN_MULT_EXPR
5982 : 32986 : || gimple_bb (def) != gimple_bb (stmt))
5983 : : return false;
5984 : 854 : tree mtype = TREE_TYPE (gimple_assign_lhs (def));
5985 : 854 : if (TREE_CODE (mtype) != INTEGER_TYPE
5986 : 854 : || TYPE_PRECISION (mtype) != TYPE_PRECISION (stype))
5987 : : return false;
5988 : :
5989 : 854 : tree mop1 = gimple_assign_rhs1 (def);
5990 : 854 : tree mop2 = gimple_assign_rhs2 (def);
5991 : 854 : tree optype = TREE_TYPE (mop1);
5992 : 854 : bool unsignedp = TYPE_UNSIGNED (optype);
5993 : 854 : unsigned int prec = TYPE_PRECISION (optype);
5994 : :
5995 : 854 : if (unsignedp != TYPE_UNSIGNED (mtype)
5996 : 854 : || TYPE_PRECISION (mtype) != 2 * prec)
5997 : : return false;
5998 : :
5999 : 854 : unsigned HOST_WIDE_INT bits = tree_to_uhwi (sarg1);
6000 : 854 : if (bits < prec || bits >= 2 * prec)
6001 : : return false;
6002 : :
6003 : : /* For the time being, require operands to have the same sign. */
6004 : 842 : if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2)))
6005 : : return false;
6006 : :
6007 : 842 : machine_mode mode = TYPE_MODE (optype);
6008 : 842 : optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
6009 : 842 : if (optab_handler (tab, mode) == CODE_FOR_nothing)
6010 : : return false;
6011 : :
6012 : 842 : location_t loc = gimple_location (stmt);
6013 : 842 : tree highpart1 = build_and_insert_binop (gsi, loc, "highparttmp",
6014 : : MULT_HIGHPART_EXPR, mop1, mop2);
6015 : 842 : tree highpart2 = highpart1;
6016 : 842 : tree ntype = optype;
6017 : :
6018 : 842 : if (TYPE_UNSIGNED (stype) != TYPE_UNSIGNED (optype))
6019 : : {
6020 : 16 : ntype = TYPE_UNSIGNED (stype) ? unsigned_type_for (optype)
6021 : 7 : : signed_type_for (optype);
6022 : 16 : highpart2 = build_and_insert_cast (gsi, loc, ntype, highpart1);
6023 : : }
6024 : 842 : if (bits > prec)
6025 : 29 : highpart2 = build_and_insert_binop (gsi, loc, "highparttmp",
6026 : : RSHIFT_EXPR, highpart2,
6027 : 29 : build_int_cst (ntype, bits - prec));
6028 : :
6029 : 842 : gassign *new_stmt = gimple_build_assign (lhs, NOP_EXPR, highpart2);
6030 : 842 : gsi_replace (gsi, new_stmt, true);
6031 : :
6032 : 842 : widen_mul_stats.highpart_mults_inserted++;
6033 : 842 : return true;
6034 : : }
6035 : :
6036 : : /* If target has spaceship<MODE>3 expander, pattern recognize
6037 : : <bb 2> [local count: 1073741824]:
6038 : : if (a_2(D) == b_3(D))
6039 : : goto <bb 6>; [34.00%]
6040 : : else
6041 : : goto <bb 3>; [66.00%]
6042 : :
6043 : : <bb 3> [local count: 708669601]:
6044 : : if (a_2(D) < b_3(D))
6045 : : goto <bb 6>; [1.04%]
6046 : : else
6047 : : goto <bb 4>; [98.96%]
6048 : :
6049 : : <bb 4> [local count: 701299439]:
6050 : : if (a_2(D) > b_3(D))
6051 : : goto <bb 5>; [48.89%]
6052 : : else
6053 : : goto <bb 6>; [51.11%]
6054 : :
6055 : : <bb 5> [local count: 342865295]:
6056 : :
6057 : : <bb 6> [local count: 1073741824]:
6058 : : and turn it into:
6059 : : <bb 2> [local count: 1073741824]:
6060 : : _1 = .SPACESHIP (a_2(D), b_3(D), 0);
6061 : : if (_1 == 0)
6062 : : goto <bb 6>; [34.00%]
6063 : : else
6064 : : goto <bb 3>; [66.00%]
6065 : :
6066 : : <bb 3> [local count: 708669601]:
6067 : : if (_1 == -1)
6068 : : goto <bb 6>; [1.04%]
6069 : : else
6070 : : goto <bb 4>; [98.96%]
6071 : :
6072 : : <bb 4> [local count: 701299439]:
6073 : : if (_1 == 1)
6074 : : goto <bb 5>; [48.89%]
6075 : : else
6076 : : goto <bb 6>; [51.11%]
6077 : :
6078 : : <bb 5> [local count: 342865295]:
6079 : :
6080 : : <bb 6> [local count: 1073741824]:
6081 : : so that the backend can emit optimal comparison and
6082 : : conditional jump sequence. If the
6083 : : <bb 6> [local count: 1073741824]:
6084 : : above has a single PHI like:
6085 : : # _27 = PHI<0(2), -1(3), -128(4), 1(5)>
6086 : : then replace it with effectively
6087 : : _1 = .SPACESHIP (a_2(D), b_3(D), -128);
6088 : : _27 = _1; */
6089 : :
6090 : : static void
6091 : 4171212 : optimize_spaceship (gcond *stmt)
6092 : : {
6093 : 4171212 : enum tree_code code = gimple_cond_code (stmt);
6094 : 4171212 : if (code != EQ_EXPR && code != NE_EXPR)
6095 : 4170966 : return;
6096 : 3383153 : tree arg1 = gimple_cond_lhs (stmt);
6097 : 3383153 : tree arg2 = gimple_cond_rhs (stmt);
6098 : 3383153 : if ((!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1))
6099 : 3274646 : && !INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
6100 : 2636364 : || optab_handler (spaceship_optab,
6101 : 2636364 : TYPE_MODE (TREE_TYPE (arg1))) == CODE_FOR_nothing
6102 : 5978627 : || operand_equal_p (arg1, arg2, 0))
6103 : 788741 : return;
6104 : :
6105 : 2594412 : basic_block bb0 = gimple_bb (stmt), bb1, bb2 = NULL;
6106 : 2594412 : edge em1 = NULL, e1 = NULL, e2 = NULL;
6107 : 2594412 : bb1 = EDGE_SUCC (bb0, 1)->dest;
6108 : 2594412 : if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
6109 : 1555571 : bb1 = EDGE_SUCC (bb0, 0)->dest;
6110 : :
6111 : 7634346 : gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
6112 : 1107167 : if (g == NULL
6113 : 1107167 : || !single_pred_p (bb1)
6114 : 721387 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6115 : 598866 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6116 : 476345 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6117 : 1715 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6118 : 608839 : || !cond_only_block_p (bb1))
6119 : 2585119 : return;
6120 : :
6121 : 9293 : enum tree_code ccode = (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6122 : 9293 : ? LT_EXPR : GT_EXPR);
6123 : 9293 : switch (gimple_cond_code (g))
6124 : : {
6125 : : case LT_EXPR:
6126 : : case LE_EXPR:
6127 : : break;
6128 : 7858 : case GT_EXPR:
6129 : 7858 : case GE_EXPR:
6130 : 7858 : ccode = ccode == LT_EXPR ? GT_EXPR : LT_EXPR;
6131 : : break;
6132 : : default:
6133 : : return;
6134 : : }
6135 : :
6136 : 27752 : for (int i = 0; i < 2; ++i)
6137 : : {
6138 : : /* With NaNs, </<=/>/>= are false, so we need to look for the
6139 : : third comparison on the false edge from whatever non-equality
6140 : : comparison the second comparison is. */
6141 : 18578 : if (HONOR_NANS (TREE_TYPE (arg1))
6142 : 18578 : && (EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0)
6143 : 253 : continue;
6144 : :
6145 : 18325 : bb2 = EDGE_SUCC (bb1, i)->dest;
6146 : 54474 : g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
6147 : 12528 : if (g == NULL
6148 : 12528 : || !single_pred_p (bb2)
6149 : 17614 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6150 : 9914 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6151 : 2214 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6152 : 12 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6153 : 119 : || !cond_only_block_p (bb2)
6154 : 10033 : || EDGE_SUCC (bb2, 0)->dest == EDGE_SUCC (bb2, 1)->dest)
6155 : 18206 : continue;
6156 : :
6157 : 119 : enum tree_code ccode2
6158 : 119 : = (operand_equal_p (gimple_cond_lhs (g), arg1, 0) ? LT_EXPR : GT_EXPR);
6159 : 119 : switch (gimple_cond_code (g))
6160 : : {
6161 : : case LT_EXPR:
6162 : : case LE_EXPR:
6163 : : break;
6164 : 53 : case GT_EXPR:
6165 : 53 : case GE_EXPR:
6166 : 53 : ccode2 = ccode2 == LT_EXPR ? GT_EXPR : LT_EXPR;
6167 : : break;
6168 : 1 : default:
6169 : 1 : continue;
6170 : : }
6171 : 118 : if (HONOR_NANS (TREE_TYPE (arg1)) && ccode == ccode2)
6172 : 0 : continue;
6173 : :
6174 : 236 : if ((ccode == LT_EXPR)
6175 : 118 : ^ ((EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0))
6176 : : {
6177 : 53 : em1 = EDGE_SUCC (bb1, 1 - i);
6178 : 53 : e1 = EDGE_SUCC (bb2, 0);
6179 : 53 : e2 = EDGE_SUCC (bb2, 1);
6180 : 53 : if ((ccode2 == LT_EXPR) ^ ((e1->flags & EDGE_TRUE_VALUE) == 0))
6181 : 0 : std::swap (e1, e2);
6182 : : }
6183 : : else
6184 : : {
6185 : 65 : e1 = EDGE_SUCC (bb1, 1 - i);
6186 : 65 : em1 = EDGE_SUCC (bb2, 0);
6187 : 65 : e2 = EDGE_SUCC (bb2, 1);
6188 : 65 : if ((ccode2 != LT_EXPR) ^ ((em1->flags & EDGE_TRUE_VALUE) == 0))
6189 : : std::swap (em1, e2);
6190 : : }
6191 : : break;
6192 : : }
6193 : :
6194 : 9227 : if (em1 == NULL)
6195 : : {
6196 : 18348 : if ((ccode == LT_EXPR)
6197 : 9174 : ^ ((EDGE_SUCC (bb1, 0)->flags & EDGE_TRUE_VALUE) != 0))
6198 : : {
6199 : 3124 : em1 = EDGE_SUCC (bb1, 1);
6200 : 3124 : e1 = EDGE_SUCC (bb1, 0);
6201 : 3124 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6202 : : }
6203 : : else
6204 : : {
6205 : 6050 : em1 = EDGE_SUCC (bb1, 0);
6206 : 6050 : e1 = EDGE_SUCC (bb1, 1);
6207 : 6050 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6208 : : }
6209 : : }
6210 : :
6211 : : /* Check if there is a single bb into which all failed conditions
6212 : : jump to (perhaps through an empty block) and if it results in
6213 : : a single integral PHI which just sets it to -1, 0, 1, X
6214 : : (or -1, 0, 1 when NaNs can't happen). In that case use 1 rather
6215 : : than 0 as last .SPACESHIP argument to tell backends it might
6216 : : consider different code generation and just cast the result
6217 : : of .SPACESHIP to the PHI result. X above is some value
6218 : : other than -1, 0, 1, for libstdc++ -128, for libc++ -127. */
6219 : 9292 : tree arg3 = integer_zero_node;
6220 : 9292 : edge e = EDGE_SUCC (bb0, 0);
6221 : 9292 : if (e->dest == bb1)
6222 : 6657 : e = EDGE_SUCC (bb0, 1);
6223 : 9292 : basic_block bbp = e->dest;
6224 : 9292 : gphi *phi = NULL;
6225 : 9292 : for (gphi_iterator psi = gsi_start_phis (bbp);
6226 : 11285 : !gsi_end_p (psi); gsi_next (&psi))
6227 : : {
6228 : 3745 : gphi *gp = psi.phi ();
6229 : 3745 : tree res = gimple_phi_result (gp);
6230 : :
6231 : 3745 : if (phi != NULL
6232 : 3394 : || virtual_operand_p (res)
6233 : 2219 : || !INTEGRAL_TYPE_P (TREE_TYPE (res))
6234 : 5860 : || TYPE_PRECISION (TREE_TYPE (res)) < 2)
6235 : : {
6236 : : phi = NULL;
6237 : : break;
6238 : : }
6239 : 1993 : phi = gp;
6240 : : }
6241 : 9292 : if (phi
6242 : 1642 : && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
6243 : 9766 : && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
6244 : : {
6245 : 95 : HOST_WIDE_INT argval
6246 : 95 : = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? -128 : -1;
6247 : 566 : for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
6248 : : {
6249 : 206 : edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
6250 : 206 : if (e3->dest != bbp)
6251 : : {
6252 : 95 : if (!empty_block_p (e3->dest)
6253 : 85 : || !single_succ_p (e3->dest)
6254 : 180 : || single_succ (e3->dest) != bbp)
6255 : : {
6256 : : phi = NULL;
6257 : : break;
6258 : : }
6259 : : e3 = single_succ_edge (e3->dest);
6260 : : }
6261 : 196 : tree a = gimple_phi_arg_def_from_edge (phi, e3);
6262 : 196 : if (TREE_CODE (a) != INTEGER_CST
6263 : 196 : || (i == 0 && !integer_onep (a))
6264 : 388 : || (i == 1 && !integer_all_onesp (a)))
6265 : : {
6266 : : phi = NULL;
6267 : : break;
6268 : : }
6269 : 192 : if (i == 2)
6270 : : {
6271 : 30 : tree minv = TYPE_MIN_VALUE (signed_char_type_node);
6272 : 30 : tree maxv = TYPE_MAX_VALUE (signed_char_type_node);
6273 : 30 : widest_int w = widest_int::from (wi::to_wide (a), SIGNED);
6274 : 41 : if ((w >= -1 && w <= 1)
6275 : 26 : || w < wi::to_widest (minv)
6276 : 56 : || w > wi::to_widest (maxv))
6277 : : {
6278 : 4 : phi = NULL;
6279 : 4 : break;
6280 : : }
6281 : 26 : argval = w.to_shwi ();
6282 : 26 : }
6283 : : }
6284 : 95 : if (phi)
6285 : 77 : arg3 = build_int_cst (integer_type_node,
6286 : 89 : TYPE_UNSIGNED (TREE_TYPE (arg1)) ? 1 : argval);
6287 : : }
6288 : :
6289 : : /* For integral <=> comparisons only use .SPACESHIP if it is turned
6290 : : into an integer (-1, 0, 1). */
6291 : 9292 : if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) && arg3 == integer_zero_node)
6292 : : return;
6293 : :
6294 : 323 : gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 3, arg1, arg2, arg3);
6295 : 323 : tree lhs = make_ssa_name (integer_type_node);
6296 : 323 : gimple_call_set_lhs (gc, lhs);
6297 : 323 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6298 : 323 : gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
6299 : :
6300 : 569 : wide_int wmin = wi::minus_one (TYPE_PRECISION (integer_type_node));
6301 : 569 : wide_int wmax = wi::one (TYPE_PRECISION (integer_type_node));
6302 : 323 : if (HONOR_NANS (TREE_TYPE (arg1)))
6303 : : {
6304 : 253 : if (arg3 == integer_zero_node)
6305 : 227 : wmin = wi::shwi (-128, TYPE_PRECISION (integer_type_node));
6306 : 26 : else if (tree_int_cst_sgn (arg3) < 0)
6307 : 19 : wmin = wi::to_wide (arg3);
6308 : : else
6309 : 7 : wmax = wi::to_wide (arg3);
6310 : : }
6311 : 569 : int_range<1> vr (TREE_TYPE (lhs), wmin, wmax);
6312 : 323 : set_range_info (lhs, vr);
6313 : :
6314 : 323 : if (arg3 != integer_zero_node)
6315 : : {
6316 : 77 : tree type = TREE_TYPE (gimple_phi_result (phi));
6317 : 77 : if (!useless_type_conversion_p (type, integer_type_node))
6318 : : {
6319 : 53 : tree tem = make_ssa_name (type);
6320 : 53 : gimple *gcv = gimple_build_assign (tem, NOP_EXPR, lhs);
6321 : 53 : gsi_insert_before (&gsi, gcv, GSI_SAME_STMT);
6322 : 53 : lhs = tem;
6323 : : }
6324 : 77 : SET_PHI_ARG_DEF_ON_EDGE (phi, e, lhs);
6325 : 77 : gimple_cond_set_lhs (stmt, boolean_false_node);
6326 : 77 : gimple_cond_set_rhs (stmt, boolean_false_node);
6327 : 141 : gimple_cond_set_code (stmt, (e->flags & EDGE_TRUE_VALUE)
6328 : : ? EQ_EXPR : NE_EXPR);
6329 : 77 : update_stmt (stmt);
6330 : 77 : return;
6331 : : }
6332 : :
6333 : 246 : gimple_cond_set_lhs (stmt, lhs);
6334 : 246 : gimple_cond_set_rhs (stmt, integer_zero_node);
6335 : 246 : update_stmt (stmt);
6336 : :
6337 : 492 : gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
6338 : 246 : gimple_cond_set_lhs (cond, lhs);
6339 : 246 : if (em1->src == bb1 && e2 != em1)
6340 : : {
6341 : 135 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6342 : 141 : gimple_cond_set_code (cond, (em1->flags & EDGE_TRUE_VALUE)
6343 : : ? EQ_EXPR : NE_EXPR);
6344 : : }
6345 : : else
6346 : : {
6347 : 111 : gcc_assert (e1->src == bb1 && e2 != e1);
6348 : 111 : gimple_cond_set_rhs (cond, integer_one_node);
6349 : 111 : gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
6350 : : ? EQ_EXPR : NE_EXPR);
6351 : : }
6352 : 246 : update_stmt (cond);
6353 : :
6354 : 246 : if (e2 != e1 && e2 != em1)
6355 : : {
6356 : 184 : cond = as_a <gcond *> (*gsi_last_bb (bb2));
6357 : 92 : gimple_cond_set_lhs (cond, lhs);
6358 : 92 : if (em1->src == bb2)
6359 : 65 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6360 : : else
6361 : : {
6362 : 27 : gcc_assert (e1->src == bb2);
6363 : 27 : gimple_cond_set_rhs (cond, integer_one_node);
6364 : : }
6365 : 92 : gimple_cond_set_code (cond,
6366 : 92 : (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
6367 : 92 : update_stmt (cond);
6368 : : }
6369 : : }
6370 : :
6371 : :
6372 : : /* Find integer multiplications where the operands are extended from
6373 : : smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
6374 : : or MULT_HIGHPART_EXPR where appropriate. */
6375 : :
6376 : : namespace {
6377 : :
6378 : : const pass_data pass_data_optimize_widening_mul =
6379 : : {
6380 : : GIMPLE_PASS, /* type */
6381 : : "widening_mul", /* name */
6382 : : OPTGROUP_NONE, /* optinfo_flags */
6383 : : TV_TREE_WIDEN_MUL, /* tv_id */
6384 : : PROP_ssa, /* properties_required */
6385 : : 0, /* properties_provided */
6386 : : 0, /* properties_destroyed */
6387 : : 0, /* todo_flags_start */
6388 : : TODO_update_ssa, /* todo_flags_finish */
6389 : : };
6390 : :
6391 : : class pass_optimize_widening_mul : public gimple_opt_pass
6392 : : {
6393 : : public:
6394 : 289080 : pass_optimize_widening_mul (gcc::context *ctxt)
6395 : 578160 : : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt)
6396 : : {}
6397 : :
6398 : : /* opt_pass methods: */
6399 : 1035897 : bool gate (function *) final override
6400 : : {
6401 : 1035897 : return flag_expensive_optimizations && optimize;
6402 : : }
6403 : :
6404 : : unsigned int execute (function *) final override;
6405 : :
6406 : : }; // class pass_optimize_widening_mul
6407 : :
6408 : : /* Walker class to perform the transformation in reverse dominance order. */
6409 : :
6410 : : class math_opts_dom_walker : public dom_walker
6411 : : {
6412 : : public:
6413 : : /* Constructor, CFG_CHANGED is a pointer to a boolean flag that will be set
6414 : : if walking modidifes the CFG. */
6415 : :
6416 : 959344 : math_opts_dom_walker (bool *cfg_changed_p)
6417 : 2878032 : : dom_walker (CDI_DOMINATORS), m_last_result_set (),
6418 : 959344 : m_cfg_changed_p (cfg_changed_p) {}
6419 : :
6420 : : /* The actual actions performed in the walk. */
6421 : :
6422 : : void after_dom_children (basic_block) final override;
6423 : :
6424 : : /* Set of results of chains of multiply and add statement combinations that
6425 : : were not transformed into FMAs because of active deferring. */
6426 : : hash_set<tree> m_last_result_set;
6427 : :
6428 : : /* Pointer to a flag of the user that needs to be set if CFG has been
6429 : : modified. */
6430 : : bool *m_cfg_changed_p;
6431 : : };
6432 : :
6433 : : void
6434 : 10584994 : math_opts_dom_walker::after_dom_children (basic_block bb)
6435 : : {
6436 : 10584994 : gimple_stmt_iterator gsi;
6437 : :
6438 : 10584994 : fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
6439 : :
6440 : 15092565 : for (gphi_iterator psi_next, psi = gsi_start_phis (bb); !gsi_end_p (psi);
6441 : 4507571 : psi = psi_next)
6442 : : {
6443 : 4507571 : psi_next = psi;
6444 : 4507571 : gsi_next (&psi_next);
6445 : :
6446 : 4507571 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
6447 : 4507571 : gphi *phi = psi.phi ();
6448 : :
6449 : 4507571 : if (match_saturation_add (&gsi, phi)
6450 : 4507554 : || match_saturation_sub (&gsi, phi)
6451 : 4507528 : || match_saturation_trunc (&gsi, phi)
6452 : 9015099 : || match_saturation_mul (&gsi, phi))
6453 : 43 : remove_phi_node (&psi, /* release_lhs_p */ false);
6454 : : }
6455 : :
6456 : 91165375 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
6457 : : {
6458 : 80580381 : gimple *stmt = gsi_stmt (gsi);
6459 : 80580381 : enum tree_code code;
6460 : :
6461 : 80580381 : if (is_gimple_assign (stmt))
6462 : : {
6463 : 21197229 : code = gimple_assign_rhs_code (stmt);
6464 : 21197229 : switch (code)
6465 : : {
6466 : 709808 : case MULT_EXPR:
6467 : 709808 : if (!convert_mult_to_widen (stmt, &gsi)
6468 : 699520 : && !convert_expand_mult_copysign (stmt, &gsi)
6469 : 1409282 : && convert_mult_to_fma (stmt,
6470 : : gimple_assign_rhs1 (stmt),
6471 : : gimple_assign_rhs2 (stmt),
6472 : : &fma_state))
6473 : : {
6474 : 16640 : gsi_remove (&gsi, true);
6475 : 16640 : release_defs (stmt);
6476 : 16640 : continue;
6477 : : }
6478 : 693168 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6479 : 693168 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6480 : 693168 : break;
6481 : :
6482 : 2239819 : case PLUS_EXPR:
6483 : 2239819 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6484 : 2239819 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6485 : : /* fall-through */
6486 : 2541575 : case MINUS_EXPR:
6487 : 2541575 : if (!convert_plusminus_to_widen (&gsi, stmt, code))
6488 : : {
6489 : 2541575 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6490 : 2541575 : if (gsi_stmt (gsi) == stmt)
6491 : 2535161 : match_uaddc_usubc (&gsi, stmt, code);
6492 : : }
6493 : : break;
6494 : :
6495 : 35992 : case BIT_NOT_EXPR:
6496 : 35992 : if (match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p))
6497 : 170 : continue;
6498 : : break;
6499 : :
6500 : 49311 : case TRUNC_MOD_EXPR:
6501 : 49311 : convert_to_divmod (as_a<gassign *> (stmt));
6502 : 49311 : break;
6503 : :
6504 : 171279 : case RSHIFT_EXPR:
6505 : 171279 : convert_mult_to_highpart (as_a<gassign *> (stmt), &gsi);
6506 : 171279 : break;
6507 : :
6508 : 189029 : case BIT_IOR_EXPR:
6509 : 189029 : match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt));
6510 : 189029 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6511 : 189029 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6512 : : /* fall-through */
6513 : 218746 : case BIT_XOR_EXPR:
6514 : 218746 : match_uaddc_usubc (&gsi, stmt, code);
6515 : 218746 : break;
6516 : :
6517 : 302972 : case EQ_EXPR:
6518 : 302972 : case NE_EXPR:
6519 : 302972 : case LE_EXPR:
6520 : 302972 : case GT_EXPR:
6521 : 302972 : match_single_bit_test (&gsi, stmt);
6522 : 302972 : break;
6523 : :
6524 : 367097 : case COND_EXPR:
6525 : 367097 : case BIT_AND_EXPR:
6526 : 367097 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6527 : 367097 : break;
6528 : :
6529 : 2406176 : case NOP_EXPR:
6530 : 2406176 : match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt));
6531 : 2406176 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6532 : 2406176 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6533 : 2406176 : break;
6534 : :
6535 : : default:;
6536 : : }
6537 : : }
6538 : 59383152 : else if (is_gimple_call (stmt))
6539 : : {
6540 : 4775791 : switch (gimple_call_combined_fn (stmt))
6541 : : {
6542 : 478 : CASE_CFN_POW:
6543 : 478 : if (gimple_call_lhs (stmt)
6544 : 438 : && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
6545 : 228 : && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
6546 : : &dconst2)
6547 : 478 : && convert_mult_to_fma (stmt,
6548 : : gimple_call_arg (stmt, 0),
6549 : : gimple_call_arg (stmt, 0),
6550 : : &fma_state))
6551 : : {
6552 : 0 : unlink_stmt_vdef (stmt);
6553 : 0 : if (gsi_remove (&gsi, true)
6554 : 0 : && gimple_purge_dead_eh_edges (bb))
6555 : 0 : *m_cfg_changed_p = true;
6556 : 0 : release_defs (stmt);
6557 : 0 : continue;
6558 : : }
6559 : : break;
6560 : :
6561 : 129 : case CFN_COND_MUL:
6562 : 129 : if (convert_mult_to_fma (stmt,
6563 : : gimple_call_arg (stmt, 1),
6564 : : gimple_call_arg (stmt, 2),
6565 : : &fma_state,
6566 : : gimple_call_arg (stmt, 0)))
6567 : :
6568 : : {
6569 : 84 : gsi_remove (&gsi, true);
6570 : 84 : release_defs (stmt);
6571 : 84 : continue;
6572 : : }
6573 : : break;
6574 : :
6575 : 0 : case CFN_COND_LEN_MUL:
6576 : 0 : if (convert_mult_to_fma (stmt,
6577 : : gimple_call_arg (stmt, 1),
6578 : : gimple_call_arg (stmt, 2),
6579 : : &fma_state,
6580 : : gimple_call_arg (stmt, 0),
6581 : : gimple_call_arg (stmt, 4),
6582 : : gimple_call_arg (stmt, 5)))
6583 : :
6584 : : {
6585 : 0 : gsi_remove (&gsi, true);
6586 : 0 : release_defs (stmt);
6587 : 0 : continue;
6588 : : }
6589 : : break;
6590 : :
6591 : 3627745 : case CFN_LAST:
6592 : 3627745 : cancel_fma_deferring (&fma_state);
6593 : 3627745 : break;
6594 : :
6595 : : default:
6596 : : break;
6597 : : }
6598 : : }
6599 : 54607361 : else if (gimple_code (stmt) == GIMPLE_COND)
6600 : : {
6601 : 4171212 : match_single_bit_test (&gsi, stmt);
6602 : 4171212 : optimize_spaceship (as_a <gcond *> (stmt));
6603 : : }
6604 : 80563487 : gsi_next (&gsi);
6605 : : }
6606 : 10584994 : if (fma_state.m_deferring_p
6607 : 7833862 : && fma_state.m_initial_phi)
6608 : : {
6609 : 361 : gcc_checking_assert (fma_state.m_last_result);
6610 : 361 : if (!last_fma_candidate_feeds_initial_phi (&fma_state,
6611 : : &m_last_result_set))
6612 : 268 : cancel_fma_deferring (&fma_state);
6613 : : else
6614 : 93 : m_last_result_set.add (fma_state.m_last_result);
6615 : : }
6616 : 10584994 : }
6617 : :
6618 : :
6619 : : unsigned int
6620 : 959344 : pass_optimize_widening_mul::execute (function *fun)
6621 : : {
6622 : 959344 : bool cfg_changed = false;
6623 : :
6624 : 959344 : memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
6625 : 959344 : calculate_dominance_info (CDI_DOMINATORS);
6626 : 959344 : renumber_gimple_stmt_uids (cfun);
6627 : :
6628 : 959344 : math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6629 : :
6630 : 959344 : statistics_counter_event (fun, "widening multiplications inserted",
6631 : : widen_mul_stats.widen_mults_inserted);
6632 : 959344 : statistics_counter_event (fun, "widening maccs inserted",
6633 : : widen_mul_stats.maccs_inserted);
6634 : 959344 : statistics_counter_event (fun, "fused multiply-adds inserted",
6635 : : widen_mul_stats.fmas_inserted);
6636 : 959344 : statistics_counter_event (fun, "divmod calls inserted",
6637 : : widen_mul_stats.divmod_calls_inserted);
6638 : 959344 : statistics_counter_event (fun, "highpart multiplications inserted",
6639 : : widen_mul_stats.highpart_mults_inserted);
6640 : :
6641 : 959344 : return cfg_changed ? TODO_cleanup_cfg : 0;
6642 : : }
6643 : :
6644 : : } // anon namespace
6645 : :
6646 : : gimple_opt_pass *
6647 : 289080 : make_pass_optimize_widening_mul (gcc::context *ctxt)
6648 : : {
6649 : 289080 : return new pass_optimize_widening_mul (ctxt);
6650 : : }
|