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 : 323577 : is_division_by (gimple *use_stmt, tree def)
353 : : {
354 : 323577 : return is_gimple_assign (use_stmt)
355 : 214459 : && 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 : 324430 : && !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 : 319896 : is_mult_by (gimple *use_stmt, tree def, tree a)
367 : : {
368 : 319896 : if (gimple_code (use_stmt) == GIMPLE_ASSIGN
369 : 319896 : && gimple_assign_rhs_code (use_stmt) == MULT_EXPR)
370 : : {
371 : 70817 : tree op0 = gimple_assign_rhs1 (use_stmt);
372 : 70817 : tree op1 = gimple_assign_rhs2 (use_stmt);
373 : :
374 : 70817 : return (op0 == def && op1 == a)
375 : 70817 : || (op0 == a && op1 == def);
376 : : }
377 : : return 0;
378 : : }
379 : :
380 : : /* Return whether USE_STMT is DEF * DEF. */
381 : : static inline bool
382 : 319851 : 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 : 196505 : execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
756 : : {
757 : 196505 : use_operand_p use_p, square_use_p;
758 : 196505 : imm_use_iterator use_iter, square_use_iter;
759 : 196505 : tree square_def;
760 : 196505 : struct occurrence *occ;
761 : 196505 : int count = 0;
762 : 196505 : int threshold;
763 : 196505 : int square_recip_count = 0;
764 : 196505 : int sqrt_recip_count = 0;
765 : :
766 : 196505 : gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && TREE_CODE (def) == SSA_NAME);
767 : 196505 : 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 : 196505 : gimple *def_stmt = SSA_NAME_DEF_STMT (def);
778 : :
779 : 196505 : if (is_gimple_assign (def_stmt)
780 : 146539 : && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
781 : 35913 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
782 : 232340 : && 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 : 516287 : FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
795 : : {
796 : 319782 : gimple *use_stmt = USE_STMT (use_p);
797 : 319782 : if (is_division_by (use_stmt, def))
798 : : {
799 : 610 : register_division_in (gimple_bb (use_stmt), 2);
800 : 610 : count++;
801 : : }
802 : :
803 : 319782 : 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 : 196505 : square_recip_count /= 2;
821 : :
822 : : /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */
823 : 196505 : 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 : 196491 : 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 : 196465 : out:
868 : 197096 : for (occ = occ_head; occ; )
869 : 591 : occ = free_bb (occ);
870 : :
871 : 196505 : occ_head = NULL;
872 : 196505 : }
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 : 285081 : pass_cse_reciprocals (gcc::context *ctxt)
921 : 570162 : : gimple_opt_pass (pass_data_cse_reciprocals, ctxt)
922 : : {}
923 : :
924 : : /* opt_pass methods: */
925 : 1021582 : bool gate (function *) final override
926 : : {
927 : 1021582 : return optimize && flag_reciprocal_math;
928 : : }
929 : : unsigned int execute (function *) final override;
930 : :
931 : : }; // class pass_cse_reciprocals
932 : :
933 : : unsigned int
934 : 8640 : pass_cse_reciprocals::execute (function *fun)
935 : : {
936 : 8640 : basic_block bb;
937 : 8640 : tree arg;
938 : :
939 : 8640 : occ_pool = new object_allocator<occurrence> ("dominators for recip");
940 : :
941 : 8640 : memset (&reciprocal_stats, 0, sizeof (reciprocal_stats));
942 : 8640 : calculate_dominance_info (CDI_DOMINATORS);
943 : 8640 : calculate_dominance_info (CDI_POST_DOMINATORS);
944 : :
945 : 8640 : if (flag_checking)
946 : 96473 : FOR_EACH_BB_FN (bb, fun)
947 : 87833 : gcc_assert (!bb->aux);
948 : :
949 : 21319 : for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg))
950 : 20108 : if (FLOAT_TYPE_P (TREE_TYPE (arg))
951 : 13764 : && is_gimple_reg (arg))
952 : : {
953 : 6334 : tree name = ssa_default_def (fun, arg);
954 : 6334 : if (name)
955 : 5339 : execute_cse_reciprocals_1 (NULL, name);
956 : : }
957 : :
958 : 96473 : FOR_EACH_BB_FN (bb, fun)
959 : : {
960 : 87833 : tree def;
961 : :
962 : 206578 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
963 : 118745 : gsi_next (&gsi))
964 : : {
965 : 118745 : gphi *phi = gsi.phi ();
966 : 118745 : def = PHI_RESULT (phi);
967 : 118745 : if (! virtual_operand_p (def)
968 : 118745 : && FLOAT_TYPE_P (TREE_TYPE (def)))
969 : 35398 : execute_cse_reciprocals_1 (NULL, def);
970 : : }
971 : :
972 : 1328212 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
973 : 1240379 : gsi_next (&gsi))
974 : : {
975 : 1240379 : gimple *stmt = gsi_stmt (gsi);
976 : :
977 : 2480758 : if (gimple_has_lhs (stmt)
978 : 769510 : && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
979 : 728154 : && FLOAT_TYPE_P (TREE_TYPE (def))
980 : 177595 : && TREE_CODE (def) == SSA_NAME)
981 : : {
982 : 155768 : execute_cse_reciprocals_1 (&gsi, def);
983 : 155768 : stmt = gsi_stmt (gsi);
984 : 155768 : if (flag_unsafe_math_optimizations
985 : 155739 : && is_gimple_assign (stmt)
986 : 146512 : && gimple_assign_lhs (stmt) == def
987 : 146510 : && !stmt_can_throw_internal (cfun, stmt)
988 : 302234 : && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
989 : 538 : optimize_recip_sqrt (&gsi, def);
990 : : }
991 : : }
992 : :
993 : 87833 : if (optimize_bb_for_size_p (bb))
994 : 5359 : continue;
995 : :
996 : : /* Scan for a/func(b) and convert it to reciprocal a*rfunc(b). */
997 : 1312881 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
998 : 1230407 : gsi_next (&gsi))
999 : : {
1000 : 1230407 : gimple *stmt = gsi_stmt (gsi);
1001 : :
1002 : 1230407 : if (is_gimple_assign (stmt)
1003 : 1230407 : && 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 : 8640 : statistics_counter_event (fun, "reciprocal divs inserted",
1098 : : reciprocal_stats.rdivs_inserted);
1099 : 8640 : statistics_counter_event (fun, "reciprocal functions inserted",
1100 : : reciprocal_stats.rfuncs_inserted);
1101 : :
1102 : 8640 : free_dominance_info (CDI_DOMINATORS);
1103 : 8640 : free_dominance_info (CDI_POST_DOMINATORS);
1104 : 17280 : delete occ_pool;
1105 : 8640 : return 0;
1106 : : }
1107 : :
1108 : : } // anon namespace
1109 : :
1110 : : gimple_opt_pass *
1111 : 285081 : make_pass_cse_reciprocals (gcc::context *ctxt)
1112 : : {
1113 : 285081 : 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 : 1028 : execute_cse_conv_1 (tree name, bool *cfg_changed)
1123 : : {
1124 : 1028 : if (SSA_NAME_IS_DEFAULT_DEF (name)
1125 : 1028 : || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
1126 : : return name;
1127 : :
1128 : 937 : gimple *def_stmt = SSA_NAME_DEF_STMT (name);
1129 : :
1130 : 937 : 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 : 1237 : maybe_record_sincos (vec<gimple *> *stmts,
1224 : : basic_block *top_bb, gimple *use_stmt)
1225 : : {
1226 : 1237 : basic_block use_bb = gimple_bb (use_stmt);
1227 : 1237 : if (*top_bb
1228 : 1237 : && (*top_bb == use_bb
1229 : 66 : || dominated_by_p (CDI_DOMINATORS, use_bb, *top_bb)))
1230 : 150 : stmts->safe_push (use_stmt);
1231 : 1087 : else if (!*top_bb
1232 : 1087 : || dominated_by_p (CDI_DOMINATORS, *top_bb, use_bb))
1233 : : {
1234 : 1067 : stmts->safe_push (use_stmt);
1235 : 1067 : *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 : 1028 : execute_cse_sincos_1 (tree name)
1253 : : {
1254 : 1028 : gimple_stmt_iterator gsi;
1255 : 1028 : imm_use_iterator use_iter;
1256 : 1028 : tree fndecl, res, type = NULL_TREE;
1257 : 1028 : gimple *def_stmt, *use_stmt, *stmt;
1258 : 1028 : int seen_cos = 0, seen_sin = 0, seen_cexpi = 0;
1259 : 1028 : auto_vec<gimple *> stmts;
1260 : 1028 : basic_block top_bb = NULL;
1261 : 1028 : int i;
1262 : 1028 : bool cfg_changed = false;
1263 : :
1264 : 1028 : name = execute_cse_conv_1 (name, &cfg_changed);
1265 : :
1266 : 3962 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, name)
1267 : : {
1268 : 2934 : if (gimple_code (use_stmt) != GIMPLE_CALL
1269 : 2934 : || !gimple_call_lhs (use_stmt))
1270 : 1668 : continue;
1271 : :
1272 : 1266 : 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 : 780 : CASE_CFN_SIN:
1279 : 780 : seen_sin |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
1280 : 780 : break;
1281 : :
1282 : 5 : CASE_CFN_CEXPI:
1283 : 5 : seen_cexpi |= maybe_record_sincos (&stmts, &top_bb, use_stmt) ? 1 : 0;
1284 : 5 : break;
1285 : :
1286 : 29 : default:;
1287 : 29 : continue;
1288 : : }
1289 : :
1290 : 1237 : tree t = mathfn_built_in_type (gimple_call_combined_fn (use_stmt));
1291 : 1237 : if (!type)
1292 : : {
1293 : 1028 : type = t;
1294 : 1028 : 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 : 1237 : if (type != t && !types_compatible_p (type, t))
1300 : 0 : return false;
1301 : 1028 : }
1302 : 1028 : 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 : 1028 : }
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 : 5978 : powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type,
1504 : : unsigned HOST_WIDE_INT n, tree *cache)
1505 : : {
1506 : 5978 : tree op0, op1, ssa_target;
1507 : 5978 : unsigned HOST_WIDE_INT digit;
1508 : 5978 : gassign *mult_stmt;
1509 : :
1510 : 5978 : if (n < POWI_TABLE_SIZE && cache[n])
1511 : : return cache[n];
1512 : :
1513 : 2121 : ssa_target = make_temp_ssa_name (type, NULL, "powmult");
1514 : :
1515 : 2121 : if (n < POWI_TABLE_SIZE)
1516 : : {
1517 : 2118 : cache[n] = ssa_target;
1518 : 2118 : op0 = powi_as_mults_1 (gsi, loc, type, n - powi_table[n], cache);
1519 : 2118 : 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 : 2121 : mult_stmt = gimple_build_assign (ssa_target, MULT_EXPR, op0, op1);
1534 : 2121 : gimple_set_location (mult_stmt, loc);
1535 : 2121 : gsi_insert_before (gsi, mult_stmt, GSI_SAME_STMT);
1536 : :
1537 : 2121 : 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 : 1738 : powi_as_mults (gimple_stmt_iterator *gsi, location_t loc,
1545 : : tree arg0, HOST_WIDE_INT n)
1546 : : {
1547 : 1738 : tree cache[POWI_TABLE_SIZE], result, type = TREE_TYPE (arg0);
1548 : 1738 : gassign *div_stmt;
1549 : 1738 : tree target;
1550 : :
1551 : 1738 : if (n == 0)
1552 : 0 : return build_one_cst (type);
1553 : :
1554 : 1738 : memset (cache, 0, sizeof (cache));
1555 : 1738 : cache[1] = arg0;
1556 : :
1557 : 1738 : result = powi_as_mults_1 (gsi, loc, type, absu_hwi (n), cache);
1558 : 1738 : 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 : 904 : 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 : 904 : tree result = make_temp_ssa_name (TREE_TYPE (arg0), NULL, name);
1621 : 904 : gassign *stmt = gimple_build_assign (result, code, arg0, arg1);
1622 : 904 : gimple_set_location (stmt, loc);
1623 : 904 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1624 : 904 : 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 : 17031 : build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
1632 : : tree type, tree val)
1633 : : {
1634 : 17031 : tree result = make_ssa_name (type);
1635 : 17031 : gassign *stmt = gimple_build_assign (result, NOP_EXPR, val);
1636 : 17031 : gimple_set_location (stmt, loc);
1637 : 17031 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1638 : 17031 : return result;
1639 : : }
1640 : :
1641 : : struct pow_synth_sqrt_info
1642 : : {
1643 : : bool *factors;
1644 : : unsigned int deepest;
1645 : : unsigned int num_mults;
1646 : : };
1647 : :
1648 : : /* Return true iff the real value C can be represented as a
1649 : : sum of powers of 0.5 up to N. That is:
1650 : : C == SUM<i from 1..N> (a[i]*(0.5**i)) where a[i] is either 0 or 1.
1651 : : Record in INFO the various parameters of the synthesis algorithm such
1652 : : as the factors a[i], the maximum 0.5 power and the number of
1653 : : multiplications that will be required. */
1654 : :
1655 : : bool
1656 : 34 : representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n,
1657 : : struct pow_synth_sqrt_info *info)
1658 : : {
1659 : 34 : REAL_VALUE_TYPE factor = dconsthalf;
1660 : 34 : REAL_VALUE_TYPE remainder = c;
1661 : :
1662 : 34 : info->deepest = 0;
1663 : 34 : info->num_mults = 0;
1664 : 34 : memset (info->factors, 0, n * sizeof (bool));
1665 : :
1666 : 98 : for (unsigned i = 0; i < n; i++)
1667 : : {
1668 : 91 : REAL_VALUE_TYPE res;
1669 : :
1670 : : /* If something inexact happened bail out now. */
1671 : 91 : if (real_arithmetic (&res, MINUS_EXPR, &remainder, &factor))
1672 : 27 : return false;
1673 : :
1674 : : /* We have hit zero. The number is representable as a sum
1675 : : of powers of 0.5. */
1676 : 91 : if (real_equal (&res, &dconst0))
1677 : : {
1678 : 27 : info->factors[i] = true;
1679 : 27 : info->deepest = i + 1;
1680 : 27 : return true;
1681 : : }
1682 : 64 : else if (!REAL_VALUE_NEGATIVE (res))
1683 : : {
1684 : 29 : remainder = res;
1685 : 29 : info->factors[i] = true;
1686 : 29 : info->num_mults++;
1687 : : }
1688 : : else
1689 : 35 : info->factors[i] = false;
1690 : :
1691 : 64 : real_arithmetic (&factor, MULT_EXPR, &factor, &dconsthalf);
1692 : : }
1693 : : return false;
1694 : : }
1695 : :
1696 : : /* Return the tree corresponding to FN being applied
1697 : : to ARG N times at GSI and LOC.
1698 : : Look up previous results from CACHE if need be.
1699 : : cache[0] should contain just plain ARG i.e. FN applied to ARG 0 times. */
1700 : :
1701 : : static tree
1702 : 65 : get_fn_chain (tree arg, unsigned int n, gimple_stmt_iterator *gsi,
1703 : : tree fn, location_t loc, tree *cache)
1704 : : {
1705 : 65 : tree res = cache[n];
1706 : 65 : if (!res)
1707 : : {
1708 : 41 : tree prev = get_fn_chain (arg, n - 1, gsi, fn, loc, cache);
1709 : 41 : res = build_and_insert_call (gsi, loc, fn, prev);
1710 : 41 : cache[n] = res;
1711 : : }
1712 : :
1713 : 65 : return res;
1714 : : }
1715 : :
1716 : : /* Print to STREAM the repeated application of function FNAME to ARG
1717 : : N times. So, for FNAME = "foo", ARG = "x", N = 2 it would print:
1718 : : "foo (foo (x))". */
1719 : :
1720 : : static void
1721 : 36 : print_nested_fn (FILE* stream, const char *fname, const char* arg,
1722 : : unsigned int n)
1723 : : {
1724 : 36 : if (n == 0)
1725 : 10 : fprintf (stream, "%s", arg);
1726 : : else
1727 : : {
1728 : 26 : fprintf (stream, "%s (", fname);
1729 : 26 : print_nested_fn (stream, fname, arg, n - 1);
1730 : 26 : fprintf (stream, ")");
1731 : : }
1732 : 36 : }
1733 : :
1734 : : /* Print to STREAM the fractional sequence of sqrt chains
1735 : : applied to ARG, described by INFO. Used for the dump file. */
1736 : :
1737 : : static void
1738 : 7 : dump_fractional_sqrt_sequence (FILE *stream, const char *arg,
1739 : : struct pow_synth_sqrt_info *info)
1740 : : {
1741 : 29 : for (unsigned int i = 0; i < info->deepest; i++)
1742 : : {
1743 : 22 : bool is_set = info->factors[i];
1744 : 22 : if (is_set)
1745 : : {
1746 : 10 : print_nested_fn (stream, "sqrt", arg, i + 1);
1747 : 10 : if (i != info->deepest - 1)
1748 : 3 : fprintf (stream, " * ");
1749 : : }
1750 : : }
1751 : 7 : }
1752 : :
1753 : : /* Print to STREAM a representation of raising ARG to an integer
1754 : : power N. Used for the dump file. */
1755 : :
1756 : : static void
1757 : 7 : dump_integer_part (FILE *stream, const char* arg, HOST_WIDE_INT n)
1758 : : {
1759 : 7 : if (n > 1)
1760 : 3 : fprintf (stream, "powi (%s, " HOST_WIDE_INT_PRINT_DEC ")", arg, n);
1761 : 4 : else if (n == 1)
1762 : 3 : fprintf (stream, "%s", arg);
1763 : 7 : }
1764 : :
1765 : : /* Attempt to synthesize a POW[F] (ARG0, ARG1) call using chains of
1766 : : square roots. Place at GSI and LOC. Limit the maximum depth
1767 : : of the sqrt chains to MAX_DEPTH. Return the tree holding the
1768 : : result of the expanded sequence or NULL_TREE if the expansion failed.
1769 : :
1770 : : This routine assumes that ARG1 is a real number with a fractional part
1771 : : (the integer exponent case will have been handled earlier in
1772 : : gimple_expand_builtin_pow).
1773 : :
1774 : : For ARG1 > 0.0:
1775 : : * For ARG1 composed of a whole part WHOLE_PART and a fractional part
1776 : : FRAC_PART i.e. WHOLE_PART == floor (ARG1) and
1777 : : FRAC_PART == ARG1 - WHOLE_PART:
1778 : : Produce POWI (ARG0, WHOLE_PART) * POW (ARG0, FRAC_PART) where
1779 : : POW (ARG0, FRAC_PART) is expanded as a product of square root chains
1780 : : if it can be expressed as such, that is if FRAC_PART satisfies:
1781 : : FRAC_PART == <SUM from i = 1 until MAX_DEPTH> (a[i] * (0.5**i))
1782 : : where integer a[i] is either 0 or 1.
1783 : :
1784 : : Example:
1785 : : POW (x, 3.625) == POWI (x, 3) * POW (x, 0.625)
1786 : : --> POWI (x, 3) * SQRT (x) * SQRT (SQRT (SQRT (x)))
1787 : :
1788 : : For ARG1 < 0.0 there are two approaches:
1789 : : * (A) Expand to 1.0 / POW (ARG0, -ARG1) where POW (ARG0, -ARG1)
1790 : : is calculated as above.
1791 : :
1792 : : Example:
1793 : : POW (x, -5.625) == 1.0 / POW (x, 5.625)
1794 : : --> 1.0 / (POWI (x, 5) * SQRT (x) * SQRT (SQRT (SQRT (x))))
1795 : :
1796 : : * (B) : WHOLE_PART := - ceil (abs (ARG1))
1797 : : FRAC_PART := ARG1 - WHOLE_PART
1798 : : and expand to POW (x, FRAC_PART) / POWI (x, WHOLE_PART).
1799 : : Example:
1800 : : POW (x, -5.875) == POW (x, 0.125) / POWI (X, 6)
1801 : : --> SQRT (SQRT (SQRT (x))) / (POWI (x, 6))
1802 : :
1803 : : For ARG1 < 0.0 we choose between (A) and (B) depending on
1804 : : how many multiplications we'd have to do.
1805 : : So, for the example in (B): POW (x, -5.875), if we were to
1806 : : follow algorithm (A) we would produce:
1807 : : 1.0 / POWI (X, 5) * SQRT (X) * SQRT (SQRT (X)) * SQRT (SQRT (SQRT (X)))
1808 : : which contains more multiplications than approach (B).
1809 : :
1810 : : Hopefully, this approach will eliminate potentially expensive POW library
1811 : : calls when unsafe floating point math is enabled and allow the compiler to
1812 : : further optimise the multiplies, square roots and divides produced by this
1813 : : function. */
1814 : :
1815 : : static tree
1816 : 26 : expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc,
1817 : : tree arg0, tree arg1, HOST_WIDE_INT max_depth)
1818 : : {
1819 : 26 : tree type = TREE_TYPE (arg0);
1820 : 26 : machine_mode mode = TYPE_MODE (type);
1821 : 26 : tree sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
1822 : 26 : bool one_over = true;
1823 : :
1824 : 26 : if (!sqrtfn)
1825 : : return NULL_TREE;
1826 : :
1827 : 26 : if (TREE_CODE (arg1) != REAL_CST)
1828 : : return NULL_TREE;
1829 : :
1830 : 26 : REAL_VALUE_TYPE exp_init = TREE_REAL_CST (arg1);
1831 : :
1832 : 26 : gcc_assert (max_depth > 0);
1833 : 26 : tree *cache = XALLOCAVEC (tree, max_depth + 1);
1834 : :
1835 : 26 : struct pow_synth_sqrt_info synth_info;
1836 : 26 : synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
1837 : 26 : synth_info.deepest = 0;
1838 : 26 : synth_info.num_mults = 0;
1839 : :
1840 : 26 : bool neg_exp = REAL_VALUE_NEGATIVE (exp_init);
1841 : 26 : REAL_VALUE_TYPE exp = real_value_abs (&exp_init);
1842 : :
1843 : : /* The whole and fractional parts of exp. */
1844 : 26 : REAL_VALUE_TYPE whole_part;
1845 : 26 : REAL_VALUE_TYPE frac_part;
1846 : :
1847 : 26 : real_floor (&whole_part, mode, &exp);
1848 : 26 : real_arithmetic (&frac_part, MINUS_EXPR, &exp, &whole_part);
1849 : :
1850 : :
1851 : 26 : REAL_VALUE_TYPE ceil_whole = dconst0;
1852 : 26 : REAL_VALUE_TYPE ceil_fract = dconst0;
1853 : :
1854 : 26 : if (neg_exp)
1855 : : {
1856 : 10 : real_ceil (&ceil_whole, mode, &exp);
1857 : 10 : real_arithmetic (&ceil_fract, MINUS_EXPR, &ceil_whole, &exp);
1858 : : }
1859 : :
1860 : 26 : if (!representable_as_half_series_p (frac_part, max_depth, &synth_info))
1861 : : return NULL_TREE;
1862 : :
1863 : : /* Check whether it's more profitable to not use 1.0 / ... */
1864 : 19 : if (neg_exp)
1865 : : {
1866 : 8 : struct pow_synth_sqrt_info alt_synth_info;
1867 : 8 : alt_synth_info.factors = XALLOCAVEC (bool, max_depth + 1);
1868 : 8 : alt_synth_info.deepest = 0;
1869 : 8 : alt_synth_info.num_mults = 0;
1870 : :
1871 : 8 : if (representable_as_half_series_p (ceil_fract, max_depth,
1872 : : &alt_synth_info)
1873 : 8 : && alt_synth_info.deepest <= synth_info.deepest
1874 : 16 : && alt_synth_info.num_mults < synth_info.num_mults)
1875 : : {
1876 : 2 : whole_part = ceil_whole;
1877 : 2 : frac_part = ceil_fract;
1878 : 2 : synth_info.deepest = alt_synth_info.deepest;
1879 : 2 : synth_info.num_mults = alt_synth_info.num_mults;
1880 : 2 : memcpy (synth_info.factors, alt_synth_info.factors,
1881 : : (max_depth + 1) * sizeof (bool));
1882 : 2 : one_over = false;
1883 : : }
1884 : : }
1885 : :
1886 : 19 : HOST_WIDE_INT n = real_to_integer (&whole_part);
1887 : 19 : REAL_VALUE_TYPE cint;
1888 : 19 : real_from_integer (&cint, VOIDmode, n, SIGNED);
1889 : :
1890 : 19 : if (!real_identical (&whole_part, &cint))
1891 : : return NULL_TREE;
1892 : :
1893 : 19 : if (powi_cost (n) + synth_info.num_mults > POWI_MAX_MULTS)
1894 : : return NULL_TREE;
1895 : :
1896 : 19 : memset (cache, 0, (max_depth + 1) * sizeof (tree));
1897 : :
1898 : 19 : tree integer_res = n == 0 ? build_real (type, dconst1) : arg0;
1899 : :
1900 : : /* Calculate the integer part of the exponent. */
1901 : 19 : if (n > 1)
1902 : : {
1903 : 7 : integer_res = gimple_expand_builtin_powi (gsi, loc, arg0, n);
1904 : 7 : if (!integer_res)
1905 : : return NULL_TREE;
1906 : : }
1907 : :
1908 : 19 : if (dump_file)
1909 : : {
1910 : 7 : char string[64];
1911 : :
1912 : 7 : real_to_decimal (string, &exp_init, sizeof (string), 0, 1);
1913 : 7 : fprintf (dump_file, "synthesizing pow (x, %s) as:\n", string);
1914 : :
1915 : 7 : if (neg_exp)
1916 : : {
1917 : 2 : if (one_over)
1918 : : {
1919 : 1 : fprintf (dump_file, "1.0 / (");
1920 : 1 : dump_integer_part (dump_file, "x", n);
1921 : 1 : if (n > 0)
1922 : 1 : fprintf (dump_file, " * ");
1923 : 1 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1924 : 1 : fprintf (dump_file, ")");
1925 : : }
1926 : : else
1927 : : {
1928 : 1 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1929 : 1 : fprintf (dump_file, " / (");
1930 : 1 : dump_integer_part (dump_file, "x", n);
1931 : 1 : fprintf (dump_file, ")");
1932 : : }
1933 : : }
1934 : : else
1935 : : {
1936 : 5 : dump_fractional_sqrt_sequence (dump_file, "x", &synth_info);
1937 : 5 : if (n > 0)
1938 : 4 : fprintf (dump_file, " * ");
1939 : 5 : dump_integer_part (dump_file, "x", n);
1940 : : }
1941 : :
1942 : 7 : fprintf (dump_file, "\ndeepest sqrt chain: %d\n", synth_info.deepest);
1943 : : }
1944 : :
1945 : :
1946 : 19 : tree fract_res = NULL_TREE;
1947 : 19 : cache[0] = arg0;
1948 : :
1949 : : /* Calculate the fractional part of the exponent. */
1950 : 60 : for (unsigned i = 0; i < synth_info.deepest; i++)
1951 : : {
1952 : 41 : if (synth_info.factors[i])
1953 : : {
1954 : 24 : tree sqrt_chain = get_fn_chain (arg0, i + 1, gsi, sqrtfn, loc, cache);
1955 : :
1956 : 24 : if (!fract_res)
1957 : : fract_res = sqrt_chain;
1958 : :
1959 : : else
1960 : 5 : fract_res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1961 : : fract_res, sqrt_chain);
1962 : : }
1963 : : }
1964 : :
1965 : 19 : tree res = NULL_TREE;
1966 : :
1967 : 19 : if (neg_exp)
1968 : : {
1969 : 8 : if (one_over)
1970 : : {
1971 : 6 : if (n > 0)
1972 : 4 : res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1973 : : fract_res, integer_res);
1974 : : else
1975 : : res = fract_res;
1976 : :
1977 : 6 : res = build_and_insert_binop (gsi, loc, "powrootrecip", RDIV_EXPR,
1978 : : build_real (type, dconst1), res);
1979 : : }
1980 : : else
1981 : : {
1982 : 2 : res = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
1983 : : fract_res, integer_res);
1984 : : }
1985 : : }
1986 : : else
1987 : 11 : res = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
1988 : : fract_res, integer_res);
1989 : : return res;
1990 : : }
1991 : :
1992 : : /* ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
1993 : : with location info LOC. If possible, create an equivalent and
1994 : : less expensive sequence of statements prior to GSI, and return an
1995 : : expession holding the result. */
1996 : :
1997 : : static tree
1998 : 585 : gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc,
1999 : : tree arg0, tree arg1)
2000 : : {
2001 : 585 : REAL_VALUE_TYPE c, cint, dconst1_3, dconst1_4, dconst1_6;
2002 : 585 : REAL_VALUE_TYPE c2, dconst3;
2003 : 585 : HOST_WIDE_INT n;
2004 : 585 : tree type, sqrtfn, cbrtfn, sqrt_arg0, result, cbrt_x, powi_cbrt_x;
2005 : 585 : machine_mode mode;
2006 : 585 : bool speed_p = optimize_bb_for_speed_p (gsi_bb (*gsi));
2007 : 585 : bool hw_sqrt_exists, c_is_int, c2_is_int;
2008 : :
2009 : 585 : dconst1_4 = dconst1;
2010 : 585 : SET_REAL_EXP (&dconst1_4, REAL_EXP (&dconst1_4) - 2);
2011 : :
2012 : : /* If the exponent isn't a constant, there's nothing of interest
2013 : : to be done. */
2014 : 585 : if (TREE_CODE (arg1) != REAL_CST)
2015 : : return NULL_TREE;
2016 : :
2017 : : /* Don't perform the operation if flag_signaling_nans is on
2018 : : and the operand is a signaling NaN. */
2019 : 355 : if (HONOR_SNANS (TYPE_MODE (TREE_TYPE (arg1)))
2020 : 355 : && ((TREE_CODE (arg0) == REAL_CST
2021 : 0 : && REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg0)))
2022 : 1 : || REAL_VALUE_ISSIGNALING_NAN (TREE_REAL_CST (arg1))))
2023 : 0 : return NULL_TREE;
2024 : :
2025 : : /* If the exponent is equivalent to an integer, expand to an optimal
2026 : : multiplication sequence when profitable. */
2027 : 355 : c = TREE_REAL_CST (arg1);
2028 : 355 : n = real_to_integer (&c);
2029 : 355 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2030 : 355 : c_is_int = real_identical (&c, &cint);
2031 : :
2032 : 355 : if (c_is_int
2033 : 355 : && ((n >= -1 && n <= 2)
2034 : 66 : || (flag_unsafe_math_optimizations
2035 : 11 : && speed_p
2036 : 11 : && powi_cost (n) <= POWI_MAX_MULTS)))
2037 : 51 : return gimple_expand_builtin_powi (gsi, loc, arg0, n);
2038 : :
2039 : : /* Attempt various optimizations using sqrt and cbrt. */
2040 : 304 : type = TREE_TYPE (arg0);
2041 : 304 : mode = TYPE_MODE (type);
2042 : 304 : sqrtfn = mathfn_built_in (type, BUILT_IN_SQRT);
2043 : :
2044 : : /* Optimize pow(x,0.5) = sqrt(x). This replacement is always safe
2045 : : unless signed zeros must be maintained. pow(-0,0.5) = +0, while
2046 : : sqrt(-0) = -0. */
2047 : 304 : if (sqrtfn
2048 : 304 : && real_equal (&c, &dconsthalf)
2049 : 312 : && !HONOR_SIGNED_ZEROS (mode))
2050 : 0 : return build_and_insert_call (gsi, loc, sqrtfn, arg0);
2051 : :
2052 : 304 : hw_sqrt_exists = optab_handler (sqrt_optab, mode) != CODE_FOR_nothing;
2053 : :
2054 : : /* Optimize pow(x,1./3.) = cbrt(x). This requires unsafe math
2055 : : optimizations since 1./3. is not exactly representable. If x
2056 : : is negative and finite, the correct value of pow(x,1./3.) is
2057 : : a NaN with the "invalid" exception raised, because the value
2058 : : of 1./3. actually has an even denominator. The correct value
2059 : : of cbrt(x) is a negative real value. */
2060 : 304 : cbrtfn = mathfn_built_in (type, BUILT_IN_CBRT);
2061 : 304 : dconst1_3 = real_value_truncate (mode, dconst_third ());
2062 : :
2063 : 304 : if (flag_unsafe_math_optimizations
2064 : 26 : && cbrtfn
2065 : 26 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2066 : 330 : && real_equal (&c, &dconst1_3))
2067 : 0 : return build_and_insert_call (gsi, loc, cbrtfn, arg0);
2068 : :
2069 : : /* Optimize pow(x,1./6.) = cbrt(sqrt(x)). Don't do this optimization
2070 : : if we don't have a hardware sqrt insn. */
2071 : 304 : dconst1_6 = dconst1_3;
2072 : 304 : SET_REAL_EXP (&dconst1_6, REAL_EXP (&dconst1_6) - 1);
2073 : :
2074 : 304 : if (flag_unsafe_math_optimizations
2075 : 26 : && sqrtfn
2076 : 26 : && cbrtfn
2077 : 26 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2078 : : && speed_p
2079 : 26 : && hw_sqrt_exists
2080 : 330 : && real_equal (&c, &dconst1_6))
2081 : : {
2082 : : /* sqrt(x) */
2083 : 0 : sqrt_arg0 = build_and_insert_call (gsi, loc, sqrtfn, arg0);
2084 : :
2085 : : /* cbrt(sqrt(x)) */
2086 : 0 : return build_and_insert_call (gsi, loc, cbrtfn, sqrt_arg0);
2087 : : }
2088 : :
2089 : :
2090 : : /* Attempt to expand the POW as a product of square root chains.
2091 : : Expand the 0.25 case even when otpimising for size. */
2092 : 304 : if (flag_unsafe_math_optimizations
2093 : 26 : && sqrtfn
2094 : 26 : && hw_sqrt_exists
2095 : 26 : && (speed_p || real_equal (&c, &dconst1_4))
2096 : 330 : && !HONOR_SIGNED_ZEROS (mode))
2097 : : {
2098 : 52 : unsigned int max_depth = speed_p
2099 : 26 : ? param_max_pow_sqrt_depth
2100 : : : 2;
2101 : :
2102 : 26 : tree expand_with_sqrts
2103 : 26 : = expand_pow_as_sqrts (gsi, loc, arg0, arg1, max_depth);
2104 : :
2105 : 26 : if (expand_with_sqrts)
2106 : : return expand_with_sqrts;
2107 : : }
2108 : :
2109 : 285 : real_arithmetic (&c2, MULT_EXPR, &c, &dconst2);
2110 : 285 : n = real_to_integer (&c2);
2111 : 285 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2112 : 285 : c2_is_int = real_identical (&c2, &cint);
2113 : :
2114 : : /* Optimize pow(x,c), where 3c = n for some nonzero integer n, into
2115 : :
2116 : : powi(x, n/3) * powi(cbrt(x), n%3), n > 0;
2117 : : 1.0 / (powi(x, abs(n)/3) * powi(cbrt(x), abs(n)%3)), n < 0.
2118 : :
2119 : : Do not calculate the first factor when n/3 = 0. As cbrt(x) is
2120 : : different from pow(x, 1./3.) due to rounding and behavior with
2121 : : negative x, we need to constrain this transformation to unsafe
2122 : : math and positive x or finite math. */
2123 : 285 : real_from_integer (&dconst3, VOIDmode, 3, SIGNED);
2124 : 285 : real_arithmetic (&c2, MULT_EXPR, &c, &dconst3);
2125 : 285 : real_round (&c2, mode, &c2);
2126 : 285 : n = real_to_integer (&c2);
2127 : 285 : real_from_integer (&cint, VOIDmode, n, SIGNED);
2128 : 285 : real_arithmetic (&c2, RDIV_EXPR, &cint, &dconst3);
2129 : 285 : real_convert (&c2, mode, &c2);
2130 : :
2131 : 285 : if (flag_unsafe_math_optimizations
2132 : 7 : && cbrtfn
2133 : 7 : && (!HONOR_NANS (mode) || tree_expr_nonnegative_p (arg0))
2134 : 7 : && real_identical (&c2, &c)
2135 : 4 : && !c2_is_int
2136 : 4 : && optimize_function_for_speed_p (cfun)
2137 : 289 : && powi_cost (n / 3) <= POWI_MAX_MULTS)
2138 : : {
2139 : 4 : tree powi_x_ndiv3 = NULL_TREE;
2140 : :
2141 : : /* Attempt to fold powi(arg0, abs(n/3)) into multiplies. If not
2142 : : possible or profitable, give up. Skip the degenerate case when
2143 : : abs(n) < 3, where the result is always 1. */
2144 : 4 : if (absu_hwi (n) >= 3)
2145 : : {
2146 : 4 : powi_x_ndiv3 = gimple_expand_builtin_powi (gsi, loc, arg0,
2147 : : abs_hwi (n / 3));
2148 : 4 : if (!powi_x_ndiv3)
2149 : : return NULL_TREE;
2150 : : }
2151 : :
2152 : : /* Calculate powi(cbrt(x), n%3). Don't use gimple_expand_builtin_powi
2153 : : as that creates an unnecessary variable. Instead, just produce
2154 : : either cbrt(x) or cbrt(x) * cbrt(x). */
2155 : 4 : cbrt_x = build_and_insert_call (gsi, loc, cbrtfn, arg0);
2156 : :
2157 : 4 : if (absu_hwi (n) % 3 == 1)
2158 : : powi_cbrt_x = cbrt_x;
2159 : : else
2160 : 2 : powi_cbrt_x = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
2161 : : cbrt_x, cbrt_x);
2162 : :
2163 : : /* Multiply the two subexpressions, unless powi(x,abs(n)/3) = 1. */
2164 : 4 : if (absu_hwi (n) < 3)
2165 : : result = powi_cbrt_x;
2166 : : else
2167 : 4 : result = build_and_insert_binop (gsi, loc, "powroot", MULT_EXPR,
2168 : : powi_x_ndiv3, powi_cbrt_x);
2169 : :
2170 : : /* If n is negative, reciprocate the result. */
2171 : 4 : if (n < 0)
2172 : 1 : result = build_and_insert_binop (gsi, loc, "powroot", RDIV_EXPR,
2173 : : build_real (type, dconst1), result);
2174 : :
2175 : 4 : return result;
2176 : : }
2177 : :
2178 : : /* No optimizations succeeded. */
2179 : : return NULL_TREE;
2180 : : }
2181 : :
2182 : : /* Go through all calls to sin, cos and cexpi and call execute_cse_sincos_1
2183 : : on the SSA_NAME argument of each of them. */
2184 : :
2185 : : namespace {
2186 : :
2187 : : const pass_data pass_data_cse_sincos =
2188 : : {
2189 : : GIMPLE_PASS, /* type */
2190 : : "sincos", /* name */
2191 : : OPTGROUP_NONE, /* optinfo_flags */
2192 : : TV_TREE_SINCOS, /* tv_id */
2193 : : PROP_ssa, /* properties_required */
2194 : : 0, /* properties_provided */
2195 : : 0, /* properties_destroyed */
2196 : : 0, /* todo_flags_start */
2197 : : TODO_update_ssa, /* todo_flags_finish */
2198 : : };
2199 : :
2200 : : class pass_cse_sincos : public gimple_opt_pass
2201 : : {
2202 : : public:
2203 : 285081 : pass_cse_sincos (gcc::context *ctxt)
2204 : 570162 : : gimple_opt_pass (pass_data_cse_sincos, ctxt)
2205 : : {}
2206 : :
2207 : : /* opt_pass methods: */
2208 : 1021582 : bool gate (function *) final override
2209 : : {
2210 : 1021582 : return optimize;
2211 : : }
2212 : :
2213 : : unsigned int execute (function *) final override;
2214 : :
2215 : : }; // class pass_cse_sincos
2216 : :
2217 : : unsigned int
2218 : 1021560 : pass_cse_sincos::execute (function *fun)
2219 : : {
2220 : 1021560 : basic_block bb;
2221 : 1021560 : bool cfg_changed = false;
2222 : :
2223 : 1021560 : calculate_dominance_info (CDI_DOMINATORS);
2224 : 1021560 : memset (&sincos_stats, 0, sizeof (sincos_stats));
2225 : :
2226 : 11288663 : FOR_EACH_BB_FN (bb, fun)
2227 : : {
2228 : 10267103 : gimple_stmt_iterator gsi;
2229 : :
2230 : 94092232 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2231 : : {
2232 : 83825129 : gimple *stmt = gsi_stmt (gsi);
2233 : :
2234 : 83825129 : if (is_gimple_call (stmt)
2235 : 83825129 : && gimple_call_lhs (stmt))
2236 : : {
2237 : 2031316 : tree arg;
2238 : 2031316 : switch (gimple_call_combined_fn (stmt))
2239 : : {
2240 : 1028 : CASE_CFN_COS:
2241 : 1028 : CASE_CFN_SIN:
2242 : 1028 : CASE_CFN_CEXPI:
2243 : 1028 : arg = gimple_call_arg (stmt, 0);
2244 : : /* Make sure we have either sincos or cexp. */
2245 : 1028 : if (!targetm.libc_has_function (function_c99_math_complex,
2246 : 1028 : TREE_TYPE (arg))
2247 : 1028 : && !targetm.libc_has_function (function_sincos,
2248 : 0 : TREE_TYPE (arg)))
2249 : : break;
2250 : :
2251 : 1028 : if (TREE_CODE (arg) == SSA_NAME)
2252 : 1028 : cfg_changed |= execute_cse_sincos_1 (arg);
2253 : : break;
2254 : : default:
2255 : : break;
2256 : : }
2257 : : }
2258 : : }
2259 : : }
2260 : :
2261 : 1021560 : statistics_counter_event (fun, "sincos statements inserted",
2262 : : sincos_stats.inserted);
2263 : 1021560 : statistics_counter_event (fun, "conv statements removed",
2264 : : sincos_stats.conv_removed);
2265 : :
2266 : 1021560 : return cfg_changed ? TODO_cleanup_cfg : 0;
2267 : : }
2268 : :
2269 : : } // anon namespace
2270 : :
2271 : : gimple_opt_pass *
2272 : 285081 : make_pass_cse_sincos (gcc::context *ctxt)
2273 : : {
2274 : 285081 : return new pass_cse_sincos (ctxt);
2275 : : }
2276 : :
2277 : : /* Expand powi(x,n) into an optimal number of multiplies, when n is a
2278 : : constant. */
2279 : : namespace {
2280 : :
2281 : : const pass_data pass_data_expand_pow =
2282 : : {
2283 : : GIMPLE_PASS, /* type */
2284 : : "pow", /* name */
2285 : : OPTGROUP_NONE, /* optinfo_flags */
2286 : : TV_TREE_POW, /* tv_id */
2287 : : PROP_ssa, /* properties_required */
2288 : : PROP_gimple_opt_math, /* properties_provided */
2289 : : 0, /* properties_destroyed */
2290 : : 0, /* todo_flags_start */
2291 : : TODO_update_ssa, /* todo_flags_finish */
2292 : : };
2293 : :
2294 : : class pass_expand_pow : public gimple_opt_pass
2295 : : {
2296 : : public:
2297 : 285081 : pass_expand_pow (gcc::context *ctxt)
2298 : 570162 : : gimple_opt_pass (pass_data_expand_pow, ctxt)
2299 : : {}
2300 : :
2301 : : /* opt_pass methods: */
2302 : 1021582 : bool gate (function *) final override
2303 : : {
2304 : 1021582 : return optimize;
2305 : : }
2306 : :
2307 : : unsigned int execute (function *) final override;
2308 : :
2309 : : }; // class pass_expand_pow
2310 : :
2311 : : unsigned int
2312 : 1021577 : pass_expand_pow::execute (function *fun)
2313 : : {
2314 : 1021577 : basic_block bb;
2315 : 1021577 : bool cfg_changed = false;
2316 : :
2317 : 1021577 : calculate_dominance_info (CDI_DOMINATORS);
2318 : :
2319 : 10510469 : FOR_EACH_BB_FN (bb, fun)
2320 : : {
2321 : 9488892 : gimple_stmt_iterator gsi;
2322 : 9488892 : bool cleanup_eh = false;
2323 : :
2324 : 91352151 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2325 : : {
2326 : 81863259 : gimple *stmt = gsi_stmt (gsi);
2327 : :
2328 : : /* Only the last stmt in a bb could throw, no need to call
2329 : : gimple_purge_dead_eh_edges if we change something in the middle
2330 : : of a basic block. */
2331 : 81863259 : cleanup_eh = false;
2332 : :
2333 : 81863259 : if (is_gimple_call (stmt)
2334 : 81863259 : && gimple_call_lhs (stmt))
2335 : : {
2336 : 2005279 : tree arg0, arg1, result;
2337 : 2005279 : HOST_WIDE_INT n;
2338 : 2005279 : location_t loc;
2339 : :
2340 : 2005279 : switch (gimple_call_combined_fn (stmt))
2341 : : {
2342 : 585 : CASE_CFN_POW:
2343 : 585 : arg0 = gimple_call_arg (stmt, 0);
2344 : 585 : arg1 = gimple_call_arg (stmt, 1);
2345 : :
2346 : 585 : loc = gimple_location (stmt);
2347 : 585 : result = gimple_expand_builtin_pow (&gsi, loc, arg0, arg1);
2348 : :
2349 : 585 : if (result)
2350 : : {
2351 : 74 : tree lhs = gimple_get_lhs (stmt);
2352 : 74 : gassign *new_stmt = gimple_build_assign (lhs, result);
2353 : 74 : gimple_set_location (new_stmt, loc);
2354 : 74 : unlink_stmt_vdef (stmt);
2355 : 74 : gsi_replace (&gsi, new_stmt, true);
2356 : 74 : cleanup_eh = true;
2357 : 148 : if (gimple_vdef (stmt))
2358 : 22 : release_ssa_name (gimple_vdef (stmt));
2359 : : }
2360 : : break;
2361 : :
2362 : 806 : CASE_CFN_POWI:
2363 : 806 : arg0 = gimple_call_arg (stmt, 0);
2364 : 806 : arg1 = gimple_call_arg (stmt, 1);
2365 : 806 : loc = gimple_location (stmt);
2366 : :
2367 : 806 : if (real_minus_onep (arg0))
2368 : : {
2369 : 11 : tree t0, t1, cond, one, minus_one;
2370 : 11 : gassign *stmt;
2371 : :
2372 : 11 : t0 = TREE_TYPE (arg0);
2373 : 11 : t1 = TREE_TYPE (arg1);
2374 : 11 : one = build_real (t0, dconst1);
2375 : 11 : minus_one = build_real (t0, dconstm1);
2376 : :
2377 : 11 : cond = make_temp_ssa_name (t1, NULL, "powi_cond");
2378 : 11 : stmt = gimple_build_assign (cond, BIT_AND_EXPR,
2379 : : arg1, build_int_cst (t1, 1));
2380 : 11 : gimple_set_location (stmt, loc);
2381 : 11 : gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2382 : :
2383 : 11 : result = make_temp_ssa_name (t0, NULL, "powi");
2384 : 11 : stmt = gimple_build_assign (result, COND_EXPR, cond,
2385 : : minus_one, one);
2386 : 11 : gimple_set_location (stmt, loc);
2387 : 11 : gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
2388 : : }
2389 : : else
2390 : : {
2391 : 795 : if (!tree_fits_shwi_p (arg1))
2392 : : break;
2393 : :
2394 : 584 : n = tree_to_shwi (arg1);
2395 : 584 : result = gimple_expand_builtin_powi (&gsi, loc, arg0, n);
2396 : : }
2397 : :
2398 : 595 : if (result)
2399 : : {
2400 : 587 : tree lhs = gimple_get_lhs (stmt);
2401 : 587 : gassign *new_stmt = gimple_build_assign (lhs, result);
2402 : 587 : gimple_set_location (new_stmt, loc);
2403 : 587 : unlink_stmt_vdef (stmt);
2404 : 587 : gsi_replace (&gsi, new_stmt, true);
2405 : 587 : cleanup_eh = true;
2406 : 81864433 : if (gimple_vdef (stmt))
2407 : 0 : release_ssa_name (gimple_vdef (stmt));
2408 : : }
2409 : : break;
2410 : :
2411 : 211 : default:;
2412 : : }
2413 : : }
2414 : : }
2415 : 9488892 : if (cleanup_eh)
2416 : 1 : cfg_changed |= gimple_purge_dead_eh_edges (bb);
2417 : : }
2418 : :
2419 : 1021577 : return cfg_changed ? TODO_cleanup_cfg : 0;
2420 : : }
2421 : :
2422 : : } // anon namespace
2423 : :
2424 : : gimple_opt_pass *
2425 : 285081 : make_pass_expand_pow (gcc::context *ctxt)
2426 : : {
2427 : 285081 : return new pass_expand_pow (ctxt);
2428 : : }
2429 : :
2430 : : /* Return true if stmt is a type conversion operation that can be stripped
2431 : : when used in a widening multiply operation. */
2432 : : static bool
2433 : 440040 : widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
2434 : : {
2435 : 440040 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
2436 : :
2437 : 440040 : if (TREE_CODE (result_type) == INTEGER_TYPE)
2438 : : {
2439 : 440040 : tree op_type;
2440 : 440040 : tree inner_op_type;
2441 : :
2442 : 440040 : if (!CONVERT_EXPR_CODE_P (rhs_code))
2443 : : return false;
2444 : :
2445 : 182657 : op_type = TREE_TYPE (gimple_assign_lhs (stmt));
2446 : :
2447 : : /* If the type of OP has the same precision as the result, then
2448 : : we can strip this conversion. The multiply operation will be
2449 : : selected to create the correct extension as a by-product. */
2450 : 182657 : if (TYPE_PRECISION (result_type) == TYPE_PRECISION (op_type))
2451 : : return true;
2452 : :
2453 : : /* We can also strip a conversion if it preserves the signed-ness of
2454 : : the operation and doesn't narrow the range. */
2455 : 1157 : inner_op_type = TREE_TYPE (gimple_assign_rhs1 (stmt));
2456 : :
2457 : : /* If the inner-most type is unsigned, then we can strip any
2458 : : intermediate widening operation. If it's signed, then the
2459 : : intermediate widening operation must also be signed. */
2460 : 1157 : if ((TYPE_UNSIGNED (inner_op_type)
2461 : 1156 : || TYPE_UNSIGNED (op_type) == TYPE_UNSIGNED (inner_op_type))
2462 : 2313 : && TYPE_PRECISION (op_type) > TYPE_PRECISION (inner_op_type))
2463 : : return true;
2464 : :
2465 : 1157 : return false;
2466 : : }
2467 : :
2468 : 0 : return rhs_code == FIXED_CONVERT_EXPR;
2469 : : }
2470 : :
2471 : : /* Return true if RHS is a suitable operand for a widening multiplication,
2472 : : assuming a target type of TYPE.
2473 : : There are two cases:
2474 : :
2475 : : - RHS makes some value at least twice as wide. Store that value
2476 : : in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.
2477 : :
2478 : : - RHS is an integer constant. Store that value in *NEW_RHS_OUT if so,
2479 : : but leave *TYPE_OUT untouched. */
2480 : :
2481 : : static bool
2482 : 916241 : is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
2483 : : tree *new_rhs_out)
2484 : : {
2485 : 916241 : gimple *stmt;
2486 : 916241 : tree type1, rhs1;
2487 : :
2488 : 916241 : if (TREE_CODE (rhs) == SSA_NAME)
2489 : : {
2490 : : /* Use tree_non_zero_bits to see if this operand is zero_extended
2491 : : for unsigned widening multiplications or non-negative for
2492 : : signed widening multiplications. */
2493 : 749211 : if (TREE_CODE (type) == INTEGER_TYPE
2494 : 749211 : && (TYPE_PRECISION (type) & 1) == 0
2495 : 1498422 : && int_mode_for_size (TYPE_PRECISION (type) / 2, 1).exists ())
2496 : : {
2497 : 743472 : unsigned int prec = TYPE_PRECISION (type);
2498 : 743472 : unsigned int hprec = prec / 2;
2499 : 743472 : wide_int bits = wide_int::from (tree_nonzero_bits (rhs), prec,
2500 : 1486944 : TYPE_SIGN (TREE_TYPE (rhs)));
2501 : 743472 : if (TYPE_UNSIGNED (type)
2502 : 1284013 : && wi::bit_and (bits, wi::mask (hprec, true, prec)) == 0)
2503 : : {
2504 : 153545 : *type_out = build_nonstandard_integer_type (hprec, true);
2505 : : /* X & MODE_MASK can be simplified to (T)X. */
2506 : 153545 : stmt = SSA_NAME_DEF_STMT (rhs);
2507 : 307090 : if (is_gimple_assign (stmt)
2508 : 134681 : && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
2509 : 16757 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
2510 : 186459 : && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
2511 : 16457 : prec, TYPE_SIGN (TREE_TYPE (rhs)))
2512 : 202916 : == wi::mask (hprec, false, prec))
2513 : 14640 : *new_rhs_out = gimple_assign_rhs1 (stmt);
2514 : : else
2515 : 138905 : *new_rhs_out = rhs;
2516 : 153545 : return true;
2517 : : }
2518 : 589927 : else if (!TYPE_UNSIGNED (type)
2519 : 792858 : && wi::bit_and (bits, wi::mask (hprec - 1, true, prec)) == 0)
2520 : : {
2521 : 29991 : *type_out = build_nonstandard_integer_type (hprec, false);
2522 : 29991 : *new_rhs_out = rhs;
2523 : 29991 : return true;
2524 : : }
2525 : 743472 : }
2526 : :
2527 : 565675 : stmt = SSA_NAME_DEF_STMT (rhs);
2528 : 565675 : if (is_gimple_assign (stmt))
2529 : : {
2530 : :
2531 : 440040 : if (widening_mult_conversion_strippable_p (type, stmt))
2532 : : {
2533 : 181500 : rhs1 = gimple_assign_rhs1 (stmt);
2534 : :
2535 : 181500 : if (TREE_CODE (rhs1) == INTEGER_CST)
2536 : : {
2537 : 0 : *new_rhs_out = rhs1;
2538 : 0 : *type_out = NULL;
2539 : 0 : return true;
2540 : : }
2541 : : }
2542 : : else
2543 : : rhs1 = rhs;
2544 : : }
2545 : : else
2546 : : rhs1 = rhs;
2547 : :
2548 : 565675 : type1 = TREE_TYPE (rhs1);
2549 : :
2550 : 565675 : if (TREE_CODE (type1) != TREE_CODE (type)
2551 : 565675 : || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
2552 : : return false;
2553 : :
2554 : 58143 : *new_rhs_out = rhs1;
2555 : 58143 : *type_out = type1;
2556 : 58143 : return true;
2557 : : }
2558 : :
2559 : 167030 : if (TREE_CODE (rhs) == INTEGER_CST)
2560 : : {
2561 : 167030 : *new_rhs_out = rhs;
2562 : 167030 : *type_out = NULL;
2563 : 167030 : return true;
2564 : : }
2565 : :
2566 : : return false;
2567 : : }
2568 : :
2569 : : /* Return true if STMT performs a widening multiplication, assuming the
2570 : : output type is TYPE. If so, store the unwidened types of the operands
2571 : : in *TYPE1_OUT and *TYPE2_OUT respectively. Also fill *RHS1_OUT and
2572 : : *RHS2_OUT such that converting those operands to types *TYPE1_OUT
2573 : : and *TYPE2_OUT would give the operands of the multiplication. */
2574 : :
2575 : : static bool
2576 : 708998 : is_widening_mult_p (gimple *stmt,
2577 : : tree *type1_out, tree *rhs1_out,
2578 : : tree *type2_out, tree *rhs2_out)
2579 : : {
2580 : 708998 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
2581 : :
2582 : 708998 : if (TREE_CODE (type) == INTEGER_TYPE)
2583 : : {
2584 : 708998 : if (TYPE_OVERFLOW_TRAPS (type))
2585 : : return false;
2586 : : }
2587 : 0 : else if (TREE_CODE (type) != FIXED_POINT_TYPE)
2588 : : return false;
2589 : :
2590 : 708970 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
2591 : : rhs1_out))
2592 : : return false;
2593 : :
2594 : 207271 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
2595 : : rhs2_out))
2596 : : return false;
2597 : :
2598 : 201438 : if (*type1_out == NULL)
2599 : : {
2600 : 0 : if (*type2_out == NULL || !int_fits_type_p (*rhs1_out, *type2_out))
2601 : : return false;
2602 : 0 : *type1_out = *type2_out;
2603 : : }
2604 : :
2605 : 201438 : if (*type2_out == NULL)
2606 : : {
2607 : 167030 : if (!int_fits_type_p (*rhs2_out, *type1_out))
2608 : : return false;
2609 : 162412 : *type2_out = *type1_out;
2610 : : }
2611 : :
2612 : : /* Ensure that the larger of the two operands comes first. */
2613 : 196820 : if (TYPE_PRECISION (*type1_out) < TYPE_PRECISION (*type2_out))
2614 : : {
2615 : 83 : std::swap (*type1_out, *type2_out);
2616 : 83 : std::swap (*rhs1_out, *rhs2_out);
2617 : : }
2618 : :
2619 : : return true;
2620 : : }
2621 : :
2622 : : /* Check to see if the CALL statement is an invocation of copysign
2623 : : with 1. being the first argument. */
2624 : : static bool
2625 : 151403 : is_copysign_call_with_1 (gimple *call)
2626 : : {
2627 : 156476 : gcall *c = dyn_cast <gcall *> (call);
2628 : 5129 : if (! c)
2629 : : return false;
2630 : :
2631 : 5129 : enum combined_fn code = gimple_call_combined_fn (c);
2632 : :
2633 : 5129 : if (code == CFN_LAST)
2634 : : return false;
2635 : :
2636 : 4224 : if (builtin_fn_p (code))
2637 : : {
2638 : 1199 : switch (as_builtin_fn (code))
2639 : : {
2640 : 30 : CASE_FLT_FN (BUILT_IN_COPYSIGN):
2641 : 30 : CASE_FLT_FN_FLOATN_NX (BUILT_IN_COPYSIGN):
2642 : 30 : return real_onep (gimple_call_arg (c, 0));
2643 : : default:
2644 : : return false;
2645 : : }
2646 : : }
2647 : :
2648 : 3025 : if (internal_fn_p (code))
2649 : : {
2650 : 3025 : switch (as_internal_fn (code))
2651 : : {
2652 : 26 : case IFN_COPYSIGN:
2653 : 26 : return real_onep (gimple_call_arg (c, 0));
2654 : : default:
2655 : : return false;
2656 : : }
2657 : : }
2658 : :
2659 : : return false;
2660 : : }
2661 : :
2662 : : /* Try to expand the pattern x * copysign (1, y) into xorsign (x, y).
2663 : : This only happens when the xorsign optab is defined, if the
2664 : : pattern is not a xorsign pattern or if expansion fails FALSE is
2665 : : returned, otherwise TRUE is returned. */
2666 : : static bool
2667 : 694341 : convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
2668 : : {
2669 : 694341 : tree treeop0, treeop1, lhs, type;
2670 : 694341 : location_t loc = gimple_location (stmt);
2671 : 694341 : lhs = gimple_assign_lhs (stmt);
2672 : 694341 : treeop0 = gimple_assign_rhs1 (stmt);
2673 : 694341 : treeop1 = gimple_assign_rhs2 (stmt);
2674 : 694341 : type = TREE_TYPE (lhs);
2675 : 694341 : machine_mode mode = TYPE_MODE (type);
2676 : :
2677 : 694341 : if (HONOR_SNANS (type))
2678 : : return false;
2679 : :
2680 : 694249 : if (TREE_CODE (treeop0) == SSA_NAME && TREE_CODE (treeop1) == SSA_NAME)
2681 : : {
2682 : 209134 : gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
2683 : 209134 : if (!has_single_use (treeop0) || !is_copysign_call_with_1 (call0))
2684 : : {
2685 : 209108 : call0 = SSA_NAME_DEF_STMT (treeop1);
2686 : 209108 : if (!has_single_use (treeop1) || !is_copysign_call_with_1 (call0))
2687 : 209088 : return false;
2688 : :
2689 : : treeop1 = treeop0;
2690 : : }
2691 : 46 : if (optab_handler (xorsign_optab, mode) == CODE_FOR_nothing)
2692 : : return false;
2693 : :
2694 : 46 : gcall *c = as_a<gcall*> (call0);
2695 : 46 : treeop0 = gimple_call_arg (c, 1);
2696 : :
2697 : 46 : gcall *call_stmt
2698 : 46 : = gimple_build_call_internal (IFN_XORSIGN, 2, treeop1, treeop0);
2699 : 46 : gimple_set_lhs (call_stmt, lhs);
2700 : 46 : gimple_set_location (call_stmt, loc);
2701 : 46 : gsi_replace (gsi, call_stmt, true);
2702 : 46 : return true;
2703 : : }
2704 : :
2705 : : return false;
2706 : : }
2707 : :
2708 : : /* Process a single gimple statement STMT, which has a MULT_EXPR as
2709 : : its rhs, and try to convert it into a WIDEN_MULT_EXPR. The return
2710 : : value is true iff we converted the statement. */
2711 : :
2712 : : static bool
2713 : 704573 : convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
2714 : : {
2715 : 704573 : tree lhs, rhs1, rhs2, type, type1, type2;
2716 : 704573 : enum insn_code handler;
2717 : 704573 : scalar_int_mode to_mode, from_mode, actual_mode;
2718 : 704573 : optab op;
2719 : 704573 : int actual_precision;
2720 : 704573 : location_t loc = gimple_location (stmt);
2721 : 704573 : bool from_unsigned1, from_unsigned2;
2722 : :
2723 : 704573 : lhs = gimple_assign_lhs (stmt);
2724 : 704573 : type = TREE_TYPE (lhs);
2725 : 704573 : if (TREE_CODE (type) != INTEGER_TYPE)
2726 : : return false;
2727 : :
2728 : 568779 : if (!is_widening_mult_p (stmt, &type1, &rhs1, &type2, &rhs2))
2729 : : return false;
2730 : :
2731 : : /* if any one of rhs1 and rhs2 is subject to abnormal coalescing,
2732 : : avoid the tranform. */
2733 : 159080 : if ((TREE_CODE (rhs1) == SSA_NAME
2734 : 159080 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2735 : 318159 : || (TREE_CODE (rhs2) == SSA_NAME
2736 : 23990 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)))
2737 : : return false;
2738 : :
2739 : 159079 : to_mode = SCALAR_INT_TYPE_MODE (type);
2740 : 159079 : from_mode = SCALAR_INT_TYPE_MODE (type1);
2741 : 159079 : if (to_mode == from_mode)
2742 : : return false;
2743 : :
2744 : 159075 : from_unsigned1 = TYPE_UNSIGNED (type1);
2745 : 159075 : from_unsigned2 = TYPE_UNSIGNED (type2);
2746 : :
2747 : 159075 : if (from_unsigned1 && from_unsigned2)
2748 : : op = umul_widen_optab;
2749 : 60142 : else if (!from_unsigned1 && !from_unsigned2)
2750 : : op = smul_widen_optab;
2751 : : else
2752 : 1905 : op = usmul_widen_optab;
2753 : :
2754 : 159075 : handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
2755 : : &actual_mode);
2756 : :
2757 : 159075 : if (handler == CODE_FOR_nothing)
2758 : : {
2759 : 148843 : if (op != smul_widen_optab)
2760 : : {
2761 : : /* We can use a signed multiply with unsigned types as long as
2762 : : there is a wider mode to use, or it is the smaller of the two
2763 : : types that is unsigned. Note that type1 >= type2, always. */
2764 : 92093 : if ((TYPE_UNSIGNED (type1)
2765 : 90374 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2766 : 92093 : || (TYPE_UNSIGNED (type2)
2767 : 1719 : && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
2768 : : {
2769 : 92093 : if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
2770 : 184186 : || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
2771 : 92093 : return false;
2772 : : }
2773 : :
2774 : 0 : op = smul_widen_optab;
2775 : 0 : handler = find_widening_optab_handler_and_mode (op, to_mode,
2776 : : from_mode,
2777 : : &actual_mode);
2778 : :
2779 : 0 : if (handler == CODE_FOR_nothing)
2780 : : return false;
2781 : :
2782 : : from_unsigned1 = from_unsigned2 = false;
2783 : : }
2784 : : else
2785 : : {
2786 : : /* Expand can synthesize smul_widen_optab if the target
2787 : : supports umul_widen_optab. */
2788 : 56750 : op = umul_widen_optab;
2789 : 56750 : handler = find_widening_optab_handler_and_mode (op, to_mode,
2790 : : from_mode,
2791 : : &actual_mode);
2792 : 56750 : if (handler == CODE_FOR_nothing)
2793 : : return false;
2794 : : }
2795 : : }
2796 : :
2797 : : /* Ensure that the inputs to the handler are in the correct precison
2798 : : for the opcode. This will be the full mode size. */
2799 : 10232 : actual_precision = GET_MODE_PRECISION (actual_mode);
2800 : 10232 : if (2 * actual_precision > TYPE_PRECISION (type))
2801 : : return false;
2802 : 10232 : if (actual_precision != TYPE_PRECISION (type1)
2803 : 10232 : || from_unsigned1 != TYPE_UNSIGNED (type1))
2804 : : {
2805 : 6 : if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
2806 : : {
2807 : 0 : if (TREE_CODE (rhs1) == INTEGER_CST)
2808 : 0 : rhs1 = fold_convert (type1, rhs1);
2809 : : else
2810 : 0 : rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
2811 : : }
2812 : 6 : type1 = build_nonstandard_integer_type (actual_precision,
2813 : : from_unsigned1);
2814 : : }
2815 : 10232 : if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
2816 : : {
2817 : 9511 : if (TREE_CODE (rhs1) == INTEGER_CST)
2818 : 0 : rhs1 = fold_convert (type1, rhs1);
2819 : : else
2820 : 9511 : rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
2821 : : }
2822 : 10232 : if (actual_precision != TYPE_PRECISION (type2)
2823 : 10232 : || from_unsigned2 != TYPE_UNSIGNED (type2))
2824 : : {
2825 : 6 : if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
2826 : : {
2827 : 6 : if (TREE_CODE (rhs2) == INTEGER_CST)
2828 : 6 : rhs2 = fold_convert (type2, rhs2);
2829 : : else
2830 : 0 : rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
2831 : : }
2832 : 6 : type2 = build_nonstandard_integer_type (actual_precision,
2833 : : from_unsigned2);
2834 : : }
2835 : 10232 : if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
2836 : : {
2837 : 9702 : if (TREE_CODE (rhs2) == INTEGER_CST)
2838 : 2198 : rhs2 = fold_convert (type2, rhs2);
2839 : : else
2840 : 7504 : rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
2841 : : }
2842 : :
2843 : 10232 : gimple_assign_set_rhs1 (stmt, rhs1);
2844 : 10232 : gimple_assign_set_rhs2 (stmt, rhs2);
2845 : 10232 : gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
2846 : 10232 : update_stmt (stmt);
2847 : 10232 : widen_mul_stats.widen_mults_inserted++;
2848 : 10232 : return true;
2849 : : }
2850 : :
2851 : : /* Process a single gimple statement STMT, which is found at the
2852 : : iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
2853 : : rhs (given by CODE), and try to convert it into a
2854 : : WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR. The return value
2855 : : is true iff we converted the statement. */
2856 : :
2857 : : static bool
2858 : 2532286 : convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
2859 : : enum tree_code code)
2860 : : {
2861 : 2532286 : gimple *rhs1_stmt = NULL, *rhs2_stmt = NULL;
2862 : 2532286 : gimple *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
2863 : 2532286 : tree type, type1, type2, optype;
2864 : 2532286 : tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
2865 : 2532286 : enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
2866 : 2532286 : optab this_optab;
2867 : 2532286 : enum tree_code wmult_code;
2868 : 2532286 : enum insn_code handler;
2869 : 2532286 : scalar_mode to_mode, from_mode, actual_mode;
2870 : 2532286 : location_t loc = gimple_location (stmt);
2871 : 2532286 : int actual_precision;
2872 : 2532286 : bool from_unsigned1, from_unsigned2;
2873 : :
2874 : 2532286 : lhs = gimple_assign_lhs (stmt);
2875 : 2532286 : type = TREE_TYPE (lhs);
2876 : 2532286 : if ((TREE_CODE (type) != INTEGER_TYPE
2877 : 394072 : && TREE_CODE (type) != FIXED_POINT_TYPE)
2878 : 2532286 : || !type_has_mode_precision_p (type))
2879 : 395826 : return false;
2880 : :
2881 : 2136460 : if (code == MINUS_EXPR)
2882 : : wmult_code = WIDEN_MULT_MINUS_EXPR;
2883 : : else
2884 : 1893728 : wmult_code = WIDEN_MULT_PLUS_EXPR;
2885 : :
2886 : 2136460 : rhs1 = gimple_assign_rhs1 (stmt);
2887 : 2136460 : rhs2 = gimple_assign_rhs2 (stmt);
2888 : :
2889 : 2136460 : if (TREE_CODE (rhs1) == SSA_NAME)
2890 : : {
2891 : 2101683 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2892 : 2101683 : if (is_gimple_assign (rhs1_stmt))
2893 : 1234254 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2894 : : }
2895 : :
2896 : 2136460 : if (TREE_CODE (rhs2) == SSA_NAME)
2897 : : {
2898 : 767814 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2899 : 767814 : if (is_gimple_assign (rhs2_stmt))
2900 : 587966 : rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
2901 : : }
2902 : :
2903 : : /* Allow for one conversion statement between the multiply
2904 : : and addition/subtraction statement. If there are more than
2905 : : one conversions then we assume they would invalidate this
2906 : : transformation. If that's not the case then they should have
2907 : : been folded before now. */
2908 : 2136460 : if (CONVERT_EXPR_CODE_P (rhs1_code))
2909 : : {
2910 : 409880 : conv1_stmt = rhs1_stmt;
2911 : 409880 : rhs1 = gimple_assign_rhs1 (rhs1_stmt);
2912 : 409880 : if (TREE_CODE (rhs1) == SSA_NAME)
2913 : : {
2914 : 344749 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2915 : 344749 : if (is_gimple_assign (rhs1_stmt))
2916 : 197049 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2917 : : }
2918 : : else
2919 : : return false;
2920 : : }
2921 : 2071329 : if (CONVERT_EXPR_CODE_P (rhs2_code))
2922 : : {
2923 : 184366 : conv2_stmt = rhs2_stmt;
2924 : 184366 : rhs2 = gimple_assign_rhs1 (rhs2_stmt);
2925 : 184366 : if (TREE_CODE (rhs2) == SSA_NAME)
2926 : : {
2927 : 172460 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2928 : 172460 : if (is_gimple_assign (rhs2_stmt))
2929 : 109304 : rhs2_code = gimple_assign_rhs_code (rhs2_stmt);
2930 : : }
2931 : : else
2932 : : return false;
2933 : : }
2934 : :
2935 : : /* If code is WIDEN_MULT_EXPR then it would seem unnecessary to call
2936 : : is_widening_mult_p, but we still need the rhs returns.
2937 : :
2938 : : It might also appear that it would be sufficient to use the existing
2939 : : operands of the widening multiply, but that would limit the choice of
2940 : : multiply-and-accumulate instructions.
2941 : :
2942 : : If the widened-multiplication result has more than one uses, it is
2943 : : probably wiser not to do the conversion. Also restrict this operation
2944 : : to single basic block to avoid moving the multiply to a different block
2945 : : with a higher execution frequency. */
2946 : 2059423 : if (code == PLUS_EXPR
2947 : 1822611 : && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
2948 : : {
2949 : 127055 : if (!has_single_use (rhs1)
2950 : 79430 : || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
2951 : 197964 : || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
2952 : : &type2, &mult_rhs2))
2953 : 104244 : return false;
2954 : : add_rhs = rhs2;
2955 : : conv_stmt = conv1_stmt;
2956 : : }
2957 : 1932368 : else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
2958 : : {
2959 : 110719 : if (!has_single_use (rhs2)
2960 : 77725 : || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
2961 : 180029 : || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
2962 : : &type2, &mult_rhs2))
2963 : 95790 : return false;
2964 : : add_rhs = rhs1;
2965 : : conv_stmt = conv2_stmt;
2966 : : }
2967 : : else
2968 : : return false;
2969 : :
2970 : 37740 : to_mode = SCALAR_TYPE_MODE (type);
2971 : 37740 : from_mode = SCALAR_TYPE_MODE (type1);
2972 : 37740 : if (to_mode == from_mode)
2973 : : return false;
2974 : :
2975 : 37737 : from_unsigned1 = TYPE_UNSIGNED (type1);
2976 : 37737 : from_unsigned2 = TYPE_UNSIGNED (type2);
2977 : 37737 : optype = type1;
2978 : :
2979 : : /* There's no such thing as a mixed sign madd yet, so use a wider mode. */
2980 : 37737 : if (from_unsigned1 != from_unsigned2)
2981 : : {
2982 : 906 : if (!INTEGRAL_TYPE_P (type))
2983 : : return false;
2984 : : /* We can use a signed multiply with unsigned types as long as
2985 : : there is a wider mode to use, or it is the smaller of the two
2986 : : types that is unsigned. Note that type1 >= type2, always. */
2987 : 906 : if ((from_unsigned1
2988 : 53 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2989 : 906 : || (from_unsigned2
2990 : 853 : && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
2991 : : {
2992 : 1776 : if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
2993 : 1812 : || GET_MODE_SIZE (from_mode) >= GET_MODE_SIZE (to_mode))
2994 : 870 : return false;
2995 : : }
2996 : :
2997 : 36 : from_unsigned1 = from_unsigned2 = false;
2998 : 36 : optype = build_nonstandard_integer_type (GET_MODE_PRECISION (from_mode),
2999 : : false);
3000 : : }
3001 : :
3002 : : /* If there was a conversion between the multiply and addition
3003 : : then we need to make sure it fits a multiply-and-accumulate.
3004 : : The should be a single mode change which does not change the
3005 : : value. */
3006 : 36867 : if (conv_stmt)
3007 : : {
3008 : : /* We use the original, unmodified data types for this. */
3009 : 751 : tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
3010 : 751 : tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
3011 : 751 : int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
3012 : 751 : bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
3013 : :
3014 : 751 : if (TYPE_PRECISION (from_type) > TYPE_PRECISION (to_type))
3015 : : {
3016 : : /* Conversion is a truncate. */
3017 : 0 : if (TYPE_PRECISION (to_type) < data_size)
3018 : : return false;
3019 : : }
3020 : 751 : else if (TYPE_PRECISION (from_type) < TYPE_PRECISION (to_type))
3021 : : {
3022 : : /* Conversion is an extend. Check it's the right sort. */
3023 : 404 : if (TYPE_UNSIGNED (from_type) != is_unsigned
3024 : 404 : && !(is_unsigned && TYPE_PRECISION (from_type) > data_size))
3025 : : return false;
3026 : : }
3027 : : /* else convert is a no-op for our purposes. */
3028 : : }
3029 : :
3030 : : /* Verify that the machine can perform a widening multiply
3031 : : accumulate in this mode/signedness combination, otherwise
3032 : : this transformation is likely to pessimize code. */
3033 : 36528 : this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
3034 : 36528 : handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
3035 : : from_mode, &actual_mode);
3036 : :
3037 : 36528 : if (handler == CODE_FOR_nothing)
3038 : : return false;
3039 : :
3040 : : /* Ensure that the inputs to the handler are in the correct precison
3041 : : for the opcode. This will be the full mode size. */
3042 : 0 : actual_precision = GET_MODE_PRECISION (actual_mode);
3043 : 0 : if (actual_precision != TYPE_PRECISION (type1)
3044 : 0 : || from_unsigned1 != TYPE_UNSIGNED (type1))
3045 : : {
3046 : 0 : if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
3047 : : {
3048 : 0 : if (TREE_CODE (mult_rhs1) == INTEGER_CST)
3049 : 0 : mult_rhs1 = fold_convert (type1, mult_rhs1);
3050 : : else
3051 : 0 : mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
3052 : : }
3053 : 0 : type1 = build_nonstandard_integer_type (actual_precision,
3054 : : from_unsigned1);
3055 : : }
3056 : 0 : if (!useless_type_conversion_p (type1, TREE_TYPE (mult_rhs1)))
3057 : : {
3058 : 0 : if (TREE_CODE (mult_rhs1) == INTEGER_CST)
3059 : 0 : mult_rhs1 = fold_convert (type1, mult_rhs1);
3060 : : else
3061 : 0 : mult_rhs1 = build_and_insert_cast (gsi, loc, type1, mult_rhs1);
3062 : : }
3063 : 0 : if (actual_precision != TYPE_PRECISION (type2)
3064 : 0 : || from_unsigned2 != TYPE_UNSIGNED (type2))
3065 : : {
3066 : 0 : if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
3067 : : {
3068 : 0 : if (TREE_CODE (mult_rhs2) == INTEGER_CST)
3069 : 0 : mult_rhs2 = fold_convert (type2, mult_rhs2);
3070 : : else
3071 : 0 : mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
3072 : : }
3073 : 0 : type2 = build_nonstandard_integer_type (actual_precision,
3074 : : from_unsigned2);
3075 : : }
3076 : 0 : if (!useless_type_conversion_p (type2, TREE_TYPE (mult_rhs2)))
3077 : : {
3078 : 0 : if (TREE_CODE (mult_rhs2) == INTEGER_CST)
3079 : 0 : mult_rhs2 = fold_convert (type2, mult_rhs2);
3080 : : else
3081 : 0 : mult_rhs2 = build_and_insert_cast (gsi, loc, type2, mult_rhs2);
3082 : : }
3083 : :
3084 : 0 : if (!useless_type_conversion_p (type, TREE_TYPE (add_rhs)))
3085 : 0 : add_rhs = build_and_insert_cast (gsi, loc, type, add_rhs);
3086 : :
3087 : 0 : gimple_assign_set_rhs_with_ops (gsi, wmult_code, mult_rhs1, mult_rhs2,
3088 : : add_rhs);
3089 : 0 : update_stmt (gsi_stmt (*gsi));
3090 : 0 : widen_mul_stats.maccs_inserted++;
3091 : 0 : return true;
3092 : : }
3093 : :
3094 : : /* Given a result MUL_RESULT which is a result of a multiplication of OP1 and
3095 : : OP2 and which we know is used in statements that can be, together with the
3096 : : multiplication, converted to FMAs, perform the transformation. */
3097 : :
3098 : : static void
3099 : 18304 : convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
3100 : : {
3101 : 18304 : tree type = TREE_TYPE (mul_result);
3102 : 18304 : gimple *use_stmt;
3103 : 18304 : imm_use_iterator imm_iter;
3104 : 18304 : gcall *fma_stmt;
3105 : :
3106 : 36679 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result)
3107 : : {
3108 : 18375 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
3109 : 18375 : tree addop, mulop1 = op1, result = mul_result;
3110 : 18375 : bool negate_p = false;
3111 : 18375 : gimple_seq seq = NULL;
3112 : :
3113 : 18375 : if (is_gimple_debug (use_stmt))
3114 : 0 : continue;
3115 : :
3116 : 18375 : if (is_gimple_assign (use_stmt)
3117 : 18375 : && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
3118 : : {
3119 : 700 : result = gimple_assign_lhs (use_stmt);
3120 : 700 : use_operand_p use_p;
3121 : 700 : gimple *neguse_stmt;
3122 : 700 : single_imm_use (gimple_assign_lhs (use_stmt), &use_p, &neguse_stmt);
3123 : 700 : gsi_remove (&gsi, true);
3124 : 700 : release_defs (use_stmt);
3125 : :
3126 : 700 : use_stmt = neguse_stmt;
3127 : 700 : gsi = gsi_for_stmt (use_stmt);
3128 : 700 : negate_p = true;
3129 : : }
3130 : :
3131 : 18375 : tree cond, else_value, ops[3], len, bias;
3132 : 18375 : tree_code code;
3133 : 18375 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code,
3134 : : ops, &else_value,
3135 : : &len, &bias))
3136 : 0 : gcc_unreachable ();
3137 : 18375 : addop = ops[0] == result ? ops[1] : ops[0];
3138 : :
3139 : 18375 : if (code == MINUS_EXPR)
3140 : : {
3141 : 6210 : if (ops[0] == result)
3142 : : /* a * b - c -> a * b + (-c) */
3143 : 2902 : addop = gimple_build (&seq, NEGATE_EXPR, type, addop);
3144 : : else
3145 : : /* a - b * c -> (-b) * c + a */
3146 : 3308 : negate_p = !negate_p;
3147 : : }
3148 : :
3149 : 18375 : if (negate_p)
3150 : 4008 : mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1);
3151 : :
3152 : 18375 : if (seq)
3153 : 6205 : gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
3154 : :
3155 : 18375 : if (len)
3156 : 0 : fma_stmt
3157 : 0 : = gimple_build_call_internal (IFN_COND_LEN_FMA, 7, cond, mulop1, op2,
3158 : : addop, else_value, len, bias);
3159 : 18375 : else if (cond)
3160 : 94 : fma_stmt = gimple_build_call_internal (IFN_COND_FMA, 5, cond, mulop1,
3161 : : op2, addop, else_value);
3162 : : else
3163 : 18281 : fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
3164 : 18375 : gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
3165 : 18375 : gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
3166 : : use_stmt));
3167 : 18375 : gsi_replace (&gsi, fma_stmt, true);
3168 : : /* Follow all SSA edges so that we generate FMS, FNMA and FNMS
3169 : : regardless of where the negation occurs. */
3170 : 18375 : gimple *orig_stmt = gsi_stmt (gsi);
3171 : 18375 : if (fold_stmt (&gsi, follow_all_ssa_edges))
3172 : : {
3173 : 6254 : if (maybe_clean_or_replace_eh_stmt (orig_stmt, gsi_stmt (gsi)))
3174 : 0 : gcc_unreachable ();
3175 : 6254 : update_stmt (gsi_stmt (gsi));
3176 : : }
3177 : :
3178 : 18375 : if (dump_file && (dump_flags & TDF_DETAILS))
3179 : : {
3180 : 3 : fprintf (dump_file, "Generated FMA ");
3181 : 3 : print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
3182 : 3 : fprintf (dump_file, "\n");
3183 : : }
3184 : :
3185 : : /* If the FMA result is negated in a single use, fold the negation
3186 : : too. */
3187 : 18375 : orig_stmt = gsi_stmt (gsi);
3188 : 18375 : use_operand_p use_p;
3189 : 18375 : gimple *neg_stmt;
3190 : 18375 : if (is_gimple_call (orig_stmt)
3191 : 18375 : && gimple_call_internal_p (orig_stmt)
3192 : 18375 : && gimple_call_lhs (orig_stmt)
3193 : 18375 : && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME
3194 : 18375 : && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt)
3195 : 13724 : && is_gimple_assign (neg_stmt)
3196 : 10725 : && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR
3197 : 19728 : && !stmt_could_throw_p (cfun, neg_stmt))
3198 : : {
3199 : 1353 : gsi = gsi_for_stmt (neg_stmt);
3200 : 1353 : if (fold_stmt (&gsi, follow_all_ssa_edges))
3201 : : {
3202 : 1353 : if (maybe_clean_or_replace_eh_stmt (neg_stmt, gsi_stmt (gsi)))
3203 : 0 : gcc_unreachable ();
3204 : 1353 : update_stmt (gsi_stmt (gsi));
3205 : 1353 : if (dump_file && (dump_flags & TDF_DETAILS))
3206 : : {
3207 : 0 : fprintf (dump_file, "Folded FMA negation ");
3208 : 0 : print_gimple_stmt (dump_file, gsi_stmt (gsi), 0, TDF_NONE);
3209 : 0 : fprintf (dump_file, "\n");
3210 : : }
3211 : : }
3212 : : }
3213 : :
3214 : 18375 : widen_mul_stats.fmas_inserted++;
3215 : 18304 : }
3216 : 18304 : }
3217 : :
3218 : : /* Data necessary to perform the actual transformation from a multiplication
3219 : : and an addition to an FMA after decision is taken it should be done and to
3220 : : then delete the multiplication statement from the function IL. */
3221 : :
3222 : : struct fma_transformation_info
3223 : : {
3224 : : gimple *mul_stmt;
3225 : : tree mul_result;
3226 : : tree op1;
3227 : : tree op2;
3228 : : };
3229 : :
3230 : : /* Structure containing the current state of FMA deferring, i.e. whether we are
3231 : : deferring, whether to continue deferring, and all data necessary to come
3232 : : back and perform all deferred transformations. */
3233 : :
3234 : 10487442 : class fma_deferring_state
3235 : : {
3236 : : public:
3237 : : /* Class constructor. Pass true as PERFORM_DEFERRING in order to actually
3238 : : do any deferring. */
3239 : :
3240 : 10487442 : fma_deferring_state (bool perform_deferring)
3241 : 10487442 : : m_candidates (), m_mul_result_set (), m_initial_phi (NULL),
3242 : 10487442 : m_last_result (NULL_TREE), m_deferring_p (perform_deferring) {}
3243 : :
3244 : : /* List of FMA candidates for which we the transformation has been determined
3245 : : possible but we at this point in BB analysis we do not consider them
3246 : : beneficial. */
3247 : : auto_vec<fma_transformation_info, 8> m_candidates;
3248 : :
3249 : : /* Set of results of multiplication that are part of an already deferred FMA
3250 : : candidates. */
3251 : : hash_set<tree> m_mul_result_set;
3252 : :
3253 : : /* The PHI that supposedly feeds back result of a FMA to another over loop
3254 : : boundary. */
3255 : : gphi *m_initial_phi;
3256 : :
3257 : : /* Result of the last produced FMA candidate or NULL if there has not been
3258 : : one. */
3259 : : tree m_last_result;
3260 : :
3261 : : /* If true, deferring might still be profitable. If false, transform all
3262 : : candidates and no longer defer. */
3263 : : bool m_deferring_p;
3264 : : };
3265 : :
3266 : : /* Transform all deferred FMA candidates and mark STATE as no longer
3267 : : deferring. */
3268 : :
3269 : : static void
3270 : 3634954 : cancel_fma_deferring (fma_deferring_state *state)
3271 : : {
3272 : 3634954 : if (!state->m_deferring_p)
3273 : : return;
3274 : :
3275 : 2656193 : for (unsigned i = 0; i < state->m_candidates.length (); i++)
3276 : : {
3277 : 954 : if (dump_file && (dump_flags & TDF_DETAILS))
3278 : 0 : fprintf (dump_file, "Generating deferred FMA\n");
3279 : :
3280 : 954 : const fma_transformation_info &fti = state->m_candidates[i];
3281 : 954 : convert_mult_to_fma_1 (fti.mul_result, fti.op1, fti.op2);
3282 : :
3283 : 954 : gimple_stmt_iterator gsi = gsi_for_stmt (fti.mul_stmt);
3284 : 954 : gsi_remove (&gsi, true);
3285 : 954 : release_defs (fti.mul_stmt);
3286 : : }
3287 : 2655239 : state->m_deferring_p = false;
3288 : : }
3289 : :
3290 : : /* If OP is an SSA name defined by a PHI node, return the PHI statement.
3291 : : Otherwise return NULL. */
3292 : :
3293 : : static gphi *
3294 : 4822 : result_of_phi (tree op)
3295 : : {
3296 : 0 : if (TREE_CODE (op) != SSA_NAME)
3297 : : return NULL;
3298 : :
3299 : 4777 : return dyn_cast <gphi *> (SSA_NAME_DEF_STMT (op));
3300 : : }
3301 : :
3302 : : /* After processing statements of a BB and recording STATE, return true if the
3303 : : initial phi is fed by the last FMA candidate result ore one such result from
3304 : : previously processed BBs marked in LAST_RESULT_SET. */
3305 : :
3306 : : static bool
3307 : 297 : last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
3308 : : hash_set<tree> *last_result_set)
3309 : : {
3310 : 297 : ssa_op_iter iter;
3311 : 297 : use_operand_p use;
3312 : 641 : FOR_EACH_PHI_ARG (use, state->m_initial_phi, iter, SSA_OP_USE)
3313 : : {
3314 : 469 : tree t = USE_FROM_PTR (use);
3315 : 469 : if (t == state->m_last_result
3316 : 469 : || last_result_set->contains (t))
3317 : 125 : return true;
3318 : : }
3319 : :
3320 : : return false;
3321 : : }
3322 : :
3323 : : /* Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
3324 : : with uses in additions and subtractions to form fused multiply-add
3325 : : operations. Returns true if successful and MUL_STMT should be removed.
3326 : : If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
3327 : : on MUL_COND, otherwise it is unconditional.
3328 : :
3329 : : If STATE indicates that we are deferring FMA transformation, that means
3330 : : that we do not produce FMAs for basic blocks which look like:
3331 : :
3332 : : <bb 6>
3333 : : # accumulator_111 = PHI <0.0(5), accumulator_66(6)>
3334 : : _65 = _14 * _16;
3335 : : accumulator_66 = _65 + accumulator_111;
3336 : :
3337 : : or its unrolled version, i.e. with several FMA candidates that feed result
3338 : : of one into the addend of another. Instead, we add them to a list in STATE
3339 : : and if we later discover an FMA candidate that is not part of such a chain,
3340 : : we go back and perform all deferred past candidates. */
3341 : :
3342 : : static bool
3343 : 694424 : convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2,
3344 : : fma_deferring_state *state, tree mul_cond = NULL_TREE,
3345 : : tree mul_len = NULL_TREE, tree mul_bias = NULL_TREE)
3346 : : {
3347 : 694424 : tree mul_result = gimple_get_lhs (mul_stmt);
3348 : : /* If there isn't a LHS then this can't be an FMA. There can be no LHS
3349 : : if the statement was left just for the side-effects. */
3350 : 694424 : if (!mul_result)
3351 : : return false;
3352 : 694424 : tree type = TREE_TYPE (mul_result);
3353 : 694424 : gimple *use_stmt, *neguse_stmt;
3354 : 694424 : use_operand_p use_p;
3355 : 694424 : imm_use_iterator imm_iter;
3356 : :
3357 : 593099 : if (FLOAT_TYPE_P (type)
3358 : 714959 : && flag_fp_contract_mode != FP_CONTRACT_FAST)
3359 : : return false;
3360 : :
3361 : : /* We don't want to do bitfield reduction ops. */
3362 : 689286 : if (INTEGRAL_TYPE_P (type)
3363 : 689286 : && (!type_has_mode_precision_p (type) || TYPE_OVERFLOW_TRAPS (type)))
3364 : : return false;
3365 : :
3366 : : /* If the target doesn't support it, don't generate it. We assume that
3367 : : if fma isn't available then fms, fnma or fnms are not either. */
3368 : 689116 : optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt));
3369 : 689116 : if (!direct_internal_fn_supported_p (IFN_FMA, type, opt_type))
3370 : : return false;
3371 : :
3372 : : /* If the multiplication has zero uses, it is kept around probably because
3373 : : of -fnon-call-exceptions. Don't optimize it away in that case,
3374 : : it is DCE job. */
3375 : 23157 : if (has_zero_uses (mul_result))
3376 : : return false;
3377 : :
3378 : 23157 : bool check_defer
3379 : 23157 : = (state->m_deferring_p
3380 : 23157 : && maybe_le (tree_to_poly_int64 (TYPE_SIZE (type)),
3381 : 23157 : param_avoid_fma_max_bits));
3382 : 23157 : bool defer = check_defer;
3383 : 23157 : bool seen_negate_p = false;
3384 : :
3385 : : /* There is no numerical difference between fused and unfused integer FMAs,
3386 : : and the assumption below that FMA is as cheap as addition is unlikely
3387 : : to be true, especially if the multiplication occurs multiple times on
3388 : : the same chain. E.g., for something like:
3389 : :
3390 : : (((a * b) + c) >> 1) + (a * b)
3391 : :
3392 : : we do not want to duplicate the a * b into two additions, not least
3393 : : because the result is not a natural FMA chain. */
3394 : 23157 : if (ANY_INTEGRAL_TYPE_P (type)
3395 : 23157 : && !has_single_use (mul_result))
3396 : : return false;
3397 : :
3398 : 23157 : if (!dbg_cnt (form_fma))
3399 : : return false;
3400 : :
3401 : : /* Make sure that the multiplication statement becomes dead after
3402 : : the transformation, thus that all uses are transformed to FMAs.
3403 : : This means we assume that an FMA operation has the same cost
3404 : : as an addition. */
3405 : 42521 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
3406 : : {
3407 : 24092 : tree result = mul_result;
3408 : 24092 : bool negate_p = false;
3409 : :
3410 : 24092 : use_stmt = USE_STMT (use_p);
3411 : :
3412 : 24092 : if (is_gimple_debug (use_stmt))
3413 : 406 : continue;
3414 : :
3415 : : /* For now restrict this operations to single basic blocks. In theory
3416 : : we would want to support sinking the multiplication in
3417 : : m = a*b;
3418 : : if ()
3419 : : ma = m + c;
3420 : : else
3421 : : d = m;
3422 : : to form a fma in the then block and sink the multiplication to the
3423 : : else block. */
3424 : 23686 : if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3425 : 4728 : return false;
3426 : :
3427 : : /* A negate on the multiplication leads to FNMA. */
3428 : 22814 : if (is_gimple_assign (use_stmt)
3429 : 22814 : && gimple_assign_rhs_code (use_stmt) == NEGATE_EXPR)
3430 : : {
3431 : 706 : ssa_op_iter iter;
3432 : 706 : use_operand_p usep;
3433 : :
3434 : : /* If (due to earlier missed optimizations) we have two
3435 : : negates of the same value, treat them as equivalent
3436 : : to a single negate with multiple uses. */
3437 : 706 : if (seen_negate_p)
3438 : 0 : return false;
3439 : :
3440 : 706 : result = gimple_assign_lhs (use_stmt);
3441 : :
3442 : : /* Make sure the negate statement becomes dead with this
3443 : : single transformation. */
3444 : 706 : if (!single_imm_use (gimple_assign_lhs (use_stmt),
3445 : : &use_p, &neguse_stmt))
3446 : : return false;
3447 : :
3448 : : /* Make sure the multiplication isn't also used on that stmt. */
3449 : 2836 : FOR_EACH_PHI_OR_STMT_USE (usep, neguse_stmt, iter, SSA_OP_USE)
3450 : 1424 : if (USE_FROM_PTR (usep) == mul_result)
3451 : : return false;
3452 : :
3453 : : /* Re-validate. */
3454 : 706 : use_stmt = neguse_stmt;
3455 : 706 : if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3456 : : return false;
3457 : :
3458 : 706 : negate_p = seen_negate_p = true;
3459 : : }
3460 : :
3461 : 22814 : tree cond, else_value, ops[3], len, bias;
3462 : 22814 : tree_code code;
3463 : 22814 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
3464 : : &else_value, &len, &bias))
3465 : : return false;
3466 : :
3467 : 20891 : switch (code)
3468 : : {
3469 : 6216 : case MINUS_EXPR:
3470 : 6216 : if (ops[1] == result)
3471 : 3308 : negate_p = !negate_p;
3472 : : break;
3473 : : case PLUS_EXPR:
3474 : : break;
3475 : : default:
3476 : : /* FMA can only be formed from PLUS and MINUS. */
3477 : : return false;
3478 : : }
3479 : :
3480 : 18980 : if (len)
3481 : : {
3482 : : /* For COND_LEN_* operations, we may have dummpy mask which is
3483 : : the all true mask. Such TREE type may be mul_cond != cond
3484 : : but we still consider they are equal. */
3485 : 0 : if (mul_cond && cond != mul_cond
3486 : 0 : && !(integer_truep (mul_cond) && integer_truep (cond)))
3487 : 0 : return false;
3488 : :
3489 : 0 : if (else_value == result)
3490 : : return false;
3491 : :
3492 : 0 : if (!direct_internal_fn_supported_p (IFN_COND_LEN_FMA, type,
3493 : : opt_type))
3494 : : return false;
3495 : :
3496 : 0 : if (mul_len)
3497 : : {
3498 : 0 : poly_int64 mul_value, value;
3499 : 0 : if (poly_int_tree_p (mul_len, &mul_value)
3500 : 0 : && poly_int_tree_p (len, &value)
3501 : 0 : && maybe_ne (mul_value, value))
3502 : 0 : return false;
3503 : 0 : else if (mul_len != len)
3504 : : return false;
3505 : :
3506 : 0 : if (wi::to_widest (mul_bias) != wi::to_widest (bias))
3507 : : return false;
3508 : : }
3509 : : }
3510 : : else
3511 : : {
3512 : 18980 : if (mul_cond && cond != mul_cond)
3513 : : return false;
3514 : :
3515 : 18968 : if (cond)
3516 : : {
3517 : 104 : if (cond == result || else_value == result)
3518 : : return false;
3519 : 94 : if (!direct_internal_fn_supported_p (IFN_COND_FMA, type,
3520 : : opt_type))
3521 : : return false;
3522 : : }
3523 : : }
3524 : :
3525 : : /* If the subtrahend (OPS[1]) is computed by a MULT_EXPR that
3526 : : we'll visit later, we might be able to get a more profitable
3527 : : match with fnma.
3528 : : OTOH, if we don't, a negate / fma pair has likely lower latency
3529 : : that a mult / subtract pair. */
3530 : 18958 : if (code == MINUS_EXPR
3531 : 6210 : && !negate_p
3532 : 2202 : && ops[0] == result
3533 : 2202 : && !direct_internal_fn_supported_p (IFN_FMS, type, opt_type)
3534 : 0 : && direct_internal_fn_supported_p (IFN_FNMA, type, opt_type)
3535 : 0 : && TREE_CODE (ops[1]) == SSA_NAME
3536 : 18958 : && has_single_use (ops[1]))
3537 : : {
3538 : 0 : gimple *stmt2 = SSA_NAME_DEF_STMT (ops[1]);
3539 : 0 : if (is_gimple_assign (stmt2)
3540 : 0 : && gimple_assign_rhs_code (stmt2) == MULT_EXPR)
3541 : : return false;
3542 : : }
3543 : :
3544 : : /* We can't handle a * b + a * b. */
3545 : 18958 : if (ops[0] == ops[1])
3546 : : return false;
3547 : : /* If deferring, make sure we are not looking at an instruction that
3548 : : wouldn't have existed if we were not. */
3549 : 18958 : if (state->m_deferring_p
3550 : 18958 : && (state->m_mul_result_set.contains (ops[0])
3551 : 6124 : || state->m_mul_result_set.contains (ops[1])))
3552 : 0 : return false;
3553 : :
3554 : 18958 : if (check_defer)
3555 : : {
3556 : 5972 : tree use_lhs = gimple_get_lhs (use_stmt);
3557 : 5972 : if (state->m_last_result)
3558 : : {
3559 : 1150 : if (ops[1] == state->m_last_result
3560 : 1150 : || ops[0] == state->m_last_result)
3561 : : defer = true;
3562 : : else
3563 : 5972 : defer = false;
3564 : : }
3565 : : else
3566 : : {
3567 : 4822 : gcc_checking_assert (!state->m_initial_phi);
3568 : 4822 : gphi *phi;
3569 : 4822 : if (ops[0] == result)
3570 : 3032 : phi = result_of_phi (ops[1]);
3571 : : else
3572 : : {
3573 : 1790 : gcc_assert (ops[1] == result);
3574 : 1790 : phi = result_of_phi (ops[0]);
3575 : : }
3576 : :
3577 : : if (phi)
3578 : : {
3579 : 901 : state->m_initial_phi = phi;
3580 : 901 : defer = true;
3581 : : }
3582 : : else
3583 : : defer = false;
3584 : : }
3585 : :
3586 : 5972 : state->m_last_result = use_lhs;
3587 : 5972 : check_defer = false;
3588 : : }
3589 : : else
3590 : : defer = false;
3591 : :
3592 : : /* While it is possible to validate whether or not the exact form that
3593 : : we've recognized is available in the backend, the assumption is that
3594 : : if the deferring logic above did not trigger, the transformation is
3595 : : never a loss. For instance, suppose the target only has the plain FMA
3596 : : pattern available. Consider a*b-c -> fma(a,b,-c): we've exchanged
3597 : : MUL+SUB for FMA+NEG, which is still two operations. Consider
3598 : : -(a*b)-c -> fma(-a,b,-c): we still have 3 operations, but in the FMA
3599 : : form the two NEGs are independent and could be run in parallel. */
3600 : : }
3601 : :
3602 : 18429 : if (defer)
3603 : : {
3604 : 1079 : fma_transformation_info fti;
3605 : 1079 : fti.mul_stmt = mul_stmt;
3606 : 1079 : fti.mul_result = mul_result;
3607 : 1079 : fti.op1 = op1;
3608 : 1079 : fti.op2 = op2;
3609 : 1079 : state->m_candidates.safe_push (fti);
3610 : 1079 : state->m_mul_result_set.add (mul_result);
3611 : :
3612 : 1079 : if (dump_file && (dump_flags & TDF_DETAILS))
3613 : : {
3614 : 0 : fprintf (dump_file, "Deferred generating FMA for multiplication ");
3615 : 0 : print_gimple_stmt (dump_file, mul_stmt, 0, TDF_NONE);
3616 : 0 : fprintf (dump_file, "\n");
3617 : : }
3618 : :
3619 : 1079 : return false;
3620 : : }
3621 : : else
3622 : : {
3623 : 17350 : if (state->m_deferring_p)
3624 : 4557 : cancel_fma_deferring (state);
3625 : 17350 : convert_mult_to_fma_1 (mul_result, op1, op2);
3626 : 17350 : return true;
3627 : : }
3628 : : }
3629 : :
3630 : :
3631 : : /* Helper function of match_arith_overflow. For MUL_OVERFLOW, if we have
3632 : : a check for non-zero like:
3633 : : _1 = x_4(D) * y_5(D);
3634 : : *res_7(D) = _1;
3635 : : if (x_4(D) != 0)
3636 : : goto <bb 3>; [50.00%]
3637 : : else
3638 : : goto <bb 4>; [50.00%]
3639 : :
3640 : : <bb 3> [local count: 536870913]:
3641 : : _2 = _1 / x_4(D);
3642 : : _9 = _2 != y_5(D);
3643 : : _10 = (int) _9;
3644 : :
3645 : : <bb 4> [local count: 1073741824]:
3646 : : # iftmp.0_3 = PHI <_10(3), 0(2)>
3647 : : then in addition to using .MUL_OVERFLOW (x_4(D), y_5(D)) we can also
3648 : : optimize the x_4(D) != 0 condition to 1. */
3649 : :
3650 : : static void
3651 : 144 : maybe_optimize_guarding_check (vec<gimple *> &mul_stmts, gimple *cond_stmt,
3652 : : gimple *div_stmt, bool *cfg_changed)
3653 : : {
3654 : 144 : basic_block bb = gimple_bb (cond_stmt);
3655 : 288 : if (gimple_bb (div_stmt) != bb || !single_pred_p (bb))
3656 : 51 : return;
3657 : 144 : edge pred_edge = single_pred_edge (bb);
3658 : 144 : basic_block pred_bb = pred_edge->src;
3659 : 144 : if (EDGE_COUNT (pred_bb->succs) != 2)
3660 : : return;
3661 : 101 : edge other_edge = EDGE_SUCC (pred_bb, EDGE_SUCC (pred_bb, 0) == pred_edge);
3662 : 101 : edge other_succ_edge = NULL;
3663 : 101 : if (gimple_code (cond_stmt) == GIMPLE_COND)
3664 : : {
3665 : 48 : if (EDGE_COUNT (bb->succs) != 2)
3666 : : return;
3667 : 48 : other_succ_edge = EDGE_SUCC (bb, 0);
3668 : 48 : if (gimple_cond_code (cond_stmt) == NE_EXPR)
3669 : : {
3670 : 24 : if (other_succ_edge->flags & EDGE_TRUE_VALUE)
3671 : 24 : other_succ_edge = EDGE_SUCC (bb, 1);
3672 : : }
3673 : : else if (other_succ_edge->flags & EDGE_FALSE_VALUE)
3674 : 48 : other_succ_edge = EDGE_SUCC (bb, 0);
3675 : 48 : if (other_edge->dest != other_succ_edge->dest)
3676 : : return;
3677 : : }
3678 : 104 : else if (!single_succ_p (bb) || other_edge->dest != single_succ (bb))
3679 : : return;
3680 : 200 : gcond *zero_cond = safe_dyn_cast <gcond *> (*gsi_last_bb (pred_bb));
3681 : 100 : if (zero_cond == NULL
3682 : 100 : || (gimple_cond_code (zero_cond)
3683 : 100 : != ((pred_edge->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR))
3684 : 100 : || !integer_zerop (gimple_cond_rhs (zero_cond)))
3685 : 0 : return;
3686 : 100 : tree zero_cond_lhs = gimple_cond_lhs (zero_cond);
3687 : 100 : if (TREE_CODE (zero_cond_lhs) != SSA_NAME)
3688 : : return;
3689 : 100 : if (gimple_assign_rhs2 (div_stmt) != zero_cond_lhs)
3690 : : {
3691 : : /* Allow the divisor to be result of a same precision cast
3692 : : from zero_cond_lhs. */
3693 : 52 : tree rhs2 = gimple_assign_rhs2 (div_stmt);
3694 : 52 : if (TREE_CODE (rhs2) != SSA_NAME)
3695 : : return;
3696 : 52 : gimple *g = SSA_NAME_DEF_STMT (rhs2);
3697 : 52 : if (!gimple_assign_cast_p (g)
3698 : 52 : || gimple_assign_rhs1 (g) != gimple_cond_lhs (zero_cond)
3699 : 52 : || !INTEGRAL_TYPE_P (TREE_TYPE (zero_cond_lhs))
3700 : 104 : || (TYPE_PRECISION (TREE_TYPE (zero_cond_lhs))
3701 : 52 : != TYPE_PRECISION (TREE_TYPE (rhs2))))
3702 : : return;
3703 : : }
3704 : 100 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
3705 : 100 : mul_stmts.quick_push (div_stmt);
3706 : 100 : if (is_gimple_debug (gsi_stmt (gsi)))
3707 : 0 : gsi_next_nondebug (&gsi);
3708 : : unsigned cast_count = 0;
3709 : 629 : while (gsi_stmt (gsi) != cond_stmt)
3710 : : {
3711 : : /* If original mul_stmt has a single use, allow it in the same bb,
3712 : : we are looking then just at __builtin_mul_overflow_p.
3713 : : Though, in that case the original mul_stmt will be replaced
3714 : : by .MUL_OVERFLOW, REALPART_EXPR and IMAGPART_EXPR stmts. */
3715 : : gimple *mul_stmt;
3716 : : unsigned int i;
3717 : 2259 : bool ok = false;
3718 : 2259 : FOR_EACH_VEC_ELT (mul_stmts, i, mul_stmt)
3719 : : {
3720 : 2113 : if (gsi_stmt (gsi) == mul_stmt)
3721 : : {
3722 : : ok = true;
3723 : : break;
3724 : : }
3725 : : }
3726 : 529 : if (!ok && gimple_assign_cast_p (gsi_stmt (gsi)) && ++cast_count < 4)
3727 : : ok = true;
3728 : 383 : if (!ok)
3729 : 51 : return;
3730 : 529 : gsi_next_nondebug (&gsi);
3731 : : }
3732 : 100 : if (gimple_code (cond_stmt) == GIMPLE_COND)
3733 : : {
3734 : 47 : basic_block succ_bb = other_edge->dest;
3735 : 75 : for (gphi_iterator gpi = gsi_start_phis (succ_bb); !gsi_end_p (gpi);
3736 : 28 : gsi_next (&gpi))
3737 : : {
3738 : 35 : gphi *phi = gpi.phi ();
3739 : 35 : tree v1 = gimple_phi_arg_def (phi, other_edge->dest_idx);
3740 : 35 : tree v2 = gimple_phi_arg_def (phi, other_succ_edge->dest_idx);
3741 : 35 : if (!operand_equal_p (v1, v2, 0))
3742 : 7 : return;
3743 : : }
3744 : : }
3745 : : else
3746 : : {
3747 : 53 : tree lhs = gimple_assign_lhs (cond_stmt);
3748 : 53 : if (!lhs || !INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
3749 : : return;
3750 : 53 : gsi_next_nondebug (&gsi);
3751 : 53 : if (!gsi_end_p (gsi))
3752 : : {
3753 : 53 : if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
3754 : : return;
3755 : 53 : gimple *cast_stmt = gsi_stmt (gsi);
3756 : 53 : if (!gimple_assign_cast_p (cast_stmt))
3757 : : return;
3758 : 53 : tree new_lhs = gimple_assign_lhs (cast_stmt);
3759 : 53 : gsi_next_nondebug (&gsi);
3760 : 53 : if (!gsi_end_p (gsi)
3761 : 53 : || !new_lhs
3762 : 53 : || !INTEGRAL_TYPE_P (TREE_TYPE (new_lhs))
3763 : 106 : || TYPE_PRECISION (TREE_TYPE (new_lhs)) <= 1)
3764 : : return;
3765 : : lhs = new_lhs;
3766 : : }
3767 : 53 : edge succ_edge = single_succ_edge (bb);
3768 : 53 : basic_block succ_bb = succ_edge->dest;
3769 : 53 : gsi = gsi_start_phis (succ_bb);
3770 : 53 : if (gsi_end_p (gsi))
3771 : : return;
3772 : 53 : gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
3773 : 53 : gsi_next (&gsi);
3774 : 53 : if (!gsi_end_p (gsi))
3775 : : return;
3776 : 53 : if (gimple_phi_arg_def (phi, succ_edge->dest_idx) != lhs)
3777 : : return;
3778 : 53 : tree other_val = gimple_phi_arg_def (phi, other_edge->dest_idx);
3779 : 53 : if (gimple_assign_rhs_code (cond_stmt) == COND_EXPR)
3780 : : {
3781 : 0 : tree cond = gimple_assign_rhs1 (cond_stmt);
3782 : 0 : if (TREE_CODE (cond) == NE_EXPR)
3783 : : {
3784 : 0 : if (!operand_equal_p (other_val,
3785 : 0 : gimple_assign_rhs3 (cond_stmt), 0))
3786 : : return;
3787 : : }
3788 : 0 : else if (!operand_equal_p (other_val,
3789 : 0 : gimple_assign_rhs2 (cond_stmt), 0))
3790 : : return;
3791 : : }
3792 : 53 : else if (gimple_assign_rhs_code (cond_stmt) == NE_EXPR)
3793 : : {
3794 : 24 : if (!integer_zerop (other_val))
3795 : : return;
3796 : : }
3797 : 29 : else if (!integer_onep (other_val))
3798 : : return;
3799 : : }
3800 : 93 : if (pred_edge->flags & EDGE_TRUE_VALUE)
3801 : 40 : gimple_cond_make_true (zero_cond);
3802 : : else
3803 : 53 : gimple_cond_make_false (zero_cond);
3804 : 93 : update_stmt (zero_cond);
3805 : 93 : *cfg_changed = true;
3806 : : }
3807 : :
3808 : : /* Helper function for arith_overflow_check_p. Return true
3809 : : if VAL1 is equal to VAL2 cast to corresponding integral type
3810 : : with other signedness or vice versa. */
3811 : :
3812 : : static bool
3813 : 382 : arith_cast_equal_p (tree val1, tree val2)
3814 : : {
3815 : 382 : if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
3816 : 65 : return wi::eq_p (wi::to_wide (val1), wi::to_wide (val2));
3817 : 317 : else if (TREE_CODE (val1) != SSA_NAME || TREE_CODE (val2) != SSA_NAME)
3818 : : return false;
3819 : 280 : if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val1))
3820 : 280 : && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val1)) == val2)
3821 : : return true;
3822 : 168 : if (gimple_assign_cast_p (SSA_NAME_DEF_STMT (val2))
3823 : 168 : && gimple_assign_rhs1 (SSA_NAME_DEF_STMT (val2)) == val1)
3824 : 120 : return true;
3825 : : return false;
3826 : : }
3827 : :
3828 : : /* Helper function of match_arith_overflow. Return 1
3829 : : if USE_STMT is unsigned overflow check ovf != 0 for
3830 : : STMT, -1 if USE_STMT is unsigned overflow check ovf == 0
3831 : : and 0 otherwise. */
3832 : :
3833 : : static int
3834 : 2784507 : arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
3835 : : tree maxval, tree *other)
3836 : : {
3837 : 2784507 : enum tree_code ccode = ERROR_MARK;
3838 : 2784507 : tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
3839 : 2784507 : enum tree_code code = gimple_assign_rhs_code (stmt);
3840 : 5554049 : tree lhs = gimple_assign_lhs (cast_stmt ? cast_stmt : stmt);
3841 : 2784507 : tree rhs1 = gimple_assign_rhs1 (stmt);
3842 : 2784507 : tree rhs2 = gimple_assign_rhs2 (stmt);
3843 : 2784507 : tree multop = NULL_TREE, divlhs = NULL_TREE;
3844 : 2784507 : gimple *cur_use_stmt = use_stmt;
3845 : :
3846 : 2784507 : if (code == MULT_EXPR)
3847 : : {
3848 : 583571 : if (!is_gimple_assign (use_stmt))
3849 : 583277 : return 0;
3850 : 485408 : if (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR)
3851 : : return 0;
3852 : 2540 : if (gimple_assign_rhs1 (use_stmt) != lhs)
3853 : : return 0;
3854 : 2477 : if (cast_stmt)
3855 : : {
3856 : 155 : if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs1))
3857 : : multop = rhs2;
3858 : 81 : else if (arith_cast_equal_p (gimple_assign_rhs2 (use_stmt), rhs2))
3859 : : multop = rhs1;
3860 : : else
3861 : : return 0;
3862 : : }
3863 : 2322 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
3864 : : multop = rhs2;
3865 : 2246 : else if (operand_equal_p (gimple_assign_rhs2 (use_stmt), rhs2, 0))
3866 : : multop = rhs1;
3867 : : else
3868 : : return 0;
3869 : 298 : if (stmt_ends_bb_p (use_stmt))
3870 : : return 0;
3871 : 298 : divlhs = gimple_assign_lhs (use_stmt);
3872 : 298 : if (!divlhs)
3873 : : return 0;
3874 : 298 : use_operand_p use;
3875 : 298 : if (!single_imm_use (divlhs, &use, &cur_use_stmt))
3876 : : return 0;
3877 : 294 : if (cast_stmt && gimple_assign_cast_p (cur_use_stmt))
3878 : : {
3879 : 4 : tree cast_lhs = gimple_assign_lhs (cur_use_stmt);
3880 : 8 : if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
3881 : 4 : && TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
3882 : 4 : && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
3883 : 4 : == TYPE_PRECISION (TREE_TYPE (divlhs)))
3884 : 8 : && single_imm_use (cast_lhs, &use, &cur_use_stmt))
3885 : : {
3886 : : cast_stmt = NULL;
3887 : : divlhs = cast_lhs;
3888 : : }
3889 : : else
3890 : 0 : return 0;
3891 : : }
3892 : : }
3893 : 2201230 : if (gimple_code (cur_use_stmt) == GIMPLE_COND)
3894 : : {
3895 : 563572 : ccode = gimple_cond_code (cur_use_stmt);
3896 : 563572 : crhs1 = gimple_cond_lhs (cur_use_stmt);
3897 : 563572 : crhs2 = gimple_cond_rhs (cur_use_stmt);
3898 : : }
3899 : 1637658 : else if (is_gimple_assign (cur_use_stmt))
3900 : : {
3901 : 807924 : if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
3902 : : {
3903 : 495920 : ccode = gimple_assign_rhs_code (cur_use_stmt);
3904 : 495920 : crhs1 = gimple_assign_rhs1 (cur_use_stmt);
3905 : 495920 : crhs2 = gimple_assign_rhs2 (cur_use_stmt);
3906 : : }
3907 : 312004 : else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
3908 : : {
3909 : 4861 : tree cond = gimple_assign_rhs1 (cur_use_stmt);
3910 : 4861 : if (COMPARISON_CLASS_P (cond))
3911 : : {
3912 : 0 : ccode = TREE_CODE (cond);
3913 : 0 : crhs1 = TREE_OPERAND (cond, 0);
3914 : 0 : crhs2 = TREE_OPERAND (cond, 1);
3915 : : }
3916 : : else
3917 : : return 0;
3918 : : }
3919 : : else
3920 : : return 0;
3921 : : }
3922 : : else
3923 : : return 0;
3924 : :
3925 : 1059492 : if (maxval
3926 : 1059492 : && ccode == RSHIFT_EXPR
3927 : 105 : && crhs1 == lhs
3928 : 25 : && TREE_CODE (crhs2) == INTEGER_CST
3929 : 1059517 : && wi::to_widest (crhs2) == TYPE_PRECISION (TREE_TYPE (maxval)))
3930 : : {
3931 : 16 : tree shiftlhs = gimple_assign_lhs (use_stmt);
3932 : 16 : if (!shiftlhs)
3933 : : return 0;
3934 : 16 : use_operand_p use;
3935 : 16 : if (!single_imm_use (shiftlhs, &use, &cur_use_stmt))
3936 : : return 0;
3937 : 12 : if (gimple_code (cur_use_stmt) == GIMPLE_COND)
3938 : : {
3939 : 0 : ccode = gimple_cond_code (cur_use_stmt);
3940 : 0 : crhs1 = gimple_cond_lhs (cur_use_stmt);
3941 : 0 : crhs2 = gimple_cond_rhs (cur_use_stmt);
3942 : : }
3943 : 12 : else if (is_gimple_assign (cur_use_stmt))
3944 : : {
3945 : 12 : if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
3946 : : {
3947 : 0 : ccode = gimple_assign_rhs_code (cur_use_stmt);
3948 : 0 : crhs1 = gimple_assign_rhs1 (cur_use_stmt);
3949 : 0 : crhs2 = gimple_assign_rhs2 (cur_use_stmt);
3950 : : }
3951 : 12 : else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
3952 : : {
3953 : 0 : tree cond = gimple_assign_rhs1 (cur_use_stmt);
3954 : 0 : if (COMPARISON_CLASS_P (cond))
3955 : : {
3956 : 0 : ccode = TREE_CODE (cond);
3957 : 0 : crhs1 = TREE_OPERAND (cond, 0);
3958 : 0 : crhs2 = TREE_OPERAND (cond, 1);
3959 : : }
3960 : : else
3961 : : return 0;
3962 : : }
3963 : : else
3964 : : {
3965 : 12 : enum tree_code sc = gimple_assign_rhs_code (cur_use_stmt);
3966 : 12 : tree castlhs = gimple_assign_lhs (cur_use_stmt);
3967 : 12 : if (!CONVERT_EXPR_CODE_P (sc)
3968 : 12 : || !castlhs
3969 : 12 : || !INTEGRAL_TYPE_P (TREE_TYPE (castlhs))
3970 : 24 : || (TYPE_PRECISION (TREE_TYPE (castlhs))
3971 : 12 : > TYPE_PRECISION (TREE_TYPE (maxval))))
3972 : : return 0;
3973 : : return 1;
3974 : : }
3975 : : }
3976 : : else
3977 : : return 0;
3978 : 0 : if ((ccode != EQ_EXPR && ccode != NE_EXPR)
3979 : 0 : || crhs1 != shiftlhs
3980 : 0 : || !integer_zerop (crhs2))
3981 : 0 : return 0;
3982 : : return 1;
3983 : : }
3984 : :
3985 : 1059476 : if (TREE_CODE_CLASS (ccode) != tcc_comparison)
3986 : : return 0;
3987 : :
3988 : 600967 : switch (ccode)
3989 : : {
3990 : 112170 : case GT_EXPR:
3991 : 112170 : case LE_EXPR:
3992 : 112170 : if (maxval)
3993 : : {
3994 : : /* r = a + b; r > maxval or r <= maxval */
3995 : 69 : if (crhs1 == lhs
3996 : 66 : && TREE_CODE (crhs2) == INTEGER_CST
3997 : 113 : && tree_int_cst_equal (crhs2, maxval))
3998 : 12 : return ccode == GT_EXPR ? 1 : -1;
3999 : : break;
4000 : : }
4001 : : /* r = a - b; r > a or r <= a
4002 : : r = a + b; a > r or a <= r or b > r or b <= r. */
4003 : 112101 : if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
4004 : 112039 : || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2)
4005 : 8720 : && crhs2 == lhs))
4006 : 9114 : return ccode == GT_EXPR ? 1 : -1;
4007 : : /* r = ~a; b > r or b <= r. */
4008 : 103319 : if (code == BIT_NOT_EXPR && crhs2 == lhs)
4009 : : {
4010 : 190 : if (other)
4011 : 95 : *other = crhs1;
4012 : 222 : return ccode == GT_EXPR ? 1 : -1;
4013 : : }
4014 : : break;
4015 : 63810 : case LT_EXPR:
4016 : 63810 : case GE_EXPR:
4017 : 63810 : if (maxval)
4018 : : break;
4019 : : /* r = a - b; a < r or a >= r
4020 : : r = a + b; r < a or r >= a or r < b or r >= b. */
4021 : 63802 : if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
4022 : 63662 : || (code == PLUS_EXPR && crhs1 == lhs
4023 : 27005 : && (crhs2 == rhs1 || crhs2 == rhs2)))
4024 : 3705 : return ccode == LT_EXPR ? 1 : -1;
4025 : : /* r = ~a; r < b or r >= b. */
4026 : 60149 : if (code == BIT_NOT_EXPR && crhs1 == lhs)
4027 : : {
4028 : 167 : if (other)
4029 : 92 : *other = crhs2;
4030 : 219 : return ccode == LT_EXPR ? 1 : -1;
4031 : : }
4032 : : break;
4033 : 424987 : case EQ_EXPR:
4034 : 424987 : case NE_EXPR:
4035 : : /* r = a * b; _1 = r / a; _1 == b
4036 : : r = a * b; _1 = r / b; _1 == a
4037 : : r = a * b; _1 = r / a; _1 != b
4038 : : r = a * b; _1 = r / b; _1 != a. */
4039 : 424987 : if (code == MULT_EXPR)
4040 : : {
4041 : 291 : if (cast_stmt)
4042 : : {
4043 : 146 : if ((crhs1 == divlhs && arith_cast_equal_p (crhs2, multop))
4044 : 146 : || (crhs2 == divlhs && arith_cast_equal_p (crhs1, multop)))
4045 : : {
4046 : 146 : use_stmt = cur_use_stmt;
4047 : 216 : return ccode == NE_EXPR ? 1 : -1;
4048 : : }
4049 : : }
4050 : 94 : else if ((crhs1 == divlhs && operand_equal_p (crhs2, multop, 0))
4051 : 145 : || (crhs2 == divlhs && crhs1 == multop))
4052 : : {
4053 : 145 : use_stmt = cur_use_stmt;
4054 : 221 : return ccode == NE_EXPR ? 1 : -1;
4055 : : }
4056 : : }
4057 : : break;
4058 : : default:
4059 : : break;
4060 : : }
4061 : : return 0;
4062 : : }
4063 : :
4064 : : extern bool gimple_unsigned_integer_sat_add (tree, tree*, tree (*)(tree));
4065 : : extern bool gimple_unsigned_integer_sat_sub (tree, tree*, tree (*)(tree));
4066 : : extern bool gimple_unsigned_integer_sat_trunc (tree, tree*, tree (*)(tree));
4067 : :
4068 : : extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
4069 : : extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
4070 : : extern bool gimple_signed_integer_sat_trunc (tree, tree*, tree (*)(tree));
4071 : :
4072 : : static void
4073 : 145 : build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi,
4074 : : internal_fn fn, tree lhs,
4075 : : tree op_0, tree op_1)
4076 : : {
4077 : 145 : if (direct_internal_fn_supported_p (fn, TREE_TYPE (lhs), OPTIMIZE_FOR_BOTH))
4078 : : {
4079 : 145 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4080 : 145 : gimple_call_set_lhs (call, lhs);
4081 : 145 : gsi_replace (gsi, call, /* update_eh_info */ true);
4082 : : }
4083 : 145 : }
4084 : :
4085 : : static bool
4086 : 35 : build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi,
4087 : : internal_fn fn, tree lhs,
4088 : : tree op_0, tree op_1)
4089 : : {
4090 : 35 : if (!direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
4091 : : return false;
4092 : :
4093 : 27 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4094 : 27 : gimple_call_set_lhs (call, lhs);
4095 : 27 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4096 : :
4097 : 27 : return true;
4098 : : }
4099 : :
4100 : : /*
4101 : : * Try to match saturation unsigned add with assign.
4102 : : * _7 = _4 + _6;
4103 : : * _8 = _4 > _7;
4104 : : * _9 = (long unsigned int) _8;
4105 : : * _10 = -_9;
4106 : : * _12 = _7 | _10;
4107 : : * =>
4108 : : * _12 = .SAT_ADD (_4, _6);
4109 : : *
4110 : : * Try to match IMM=-1 saturation signed add with assign.
4111 : : * <bb 2> [local count: 1073741824]:
4112 : : * x.0_1 = (unsigned char) x_5(D);
4113 : : * _3 = -x.0_1;
4114 : : * _10 = (signed char) _3;
4115 : : * _8 = x_5(D) & _10;
4116 : : * if (_8 < 0)
4117 : : * goto <bb 4>; [1.40%]
4118 : : * else
4119 : : * goto <bb 3>; [98.60%]
4120 : : * <bb 3> [local count: 434070867]:
4121 : : * _2 = x.0_1 + 255;
4122 : : * <bb 4> [local count: 1073741824]:
4123 : : * # _9 = PHI <_2(3), 128(2)>
4124 : : * _4 = (int8_t) _9;
4125 : : * =>
4126 : : * _4 = .SAT_ADD (x_5, -1); */
4127 : :
4128 : : static void
4129 : 4824895 : match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
4130 : : {
4131 : 4824895 : tree ops[2];
4132 : 4824895 : tree lhs = gimple_assign_lhs (stmt);
4133 : :
4134 : 4824895 : if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
4135 : 4824895 : || gimple_signed_integer_sat_add (lhs, ops, NULL))
4136 : 34 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
4137 : : ops[0], ops[1]);
4138 : 4824895 : }
4139 : :
4140 : : /*
4141 : : * Try to match saturation add with PHI.
4142 : : * For unsigned integer:
4143 : : * <bb 2> :
4144 : : * _1 = x_3(D) + y_4(D);
4145 : : * if (_1 >= x_3(D))
4146 : : * goto <bb 3>; [INV]
4147 : : * else
4148 : : * goto <bb 4>; [INV]
4149 : : *
4150 : : * <bb 3> :
4151 : : *
4152 : : * <bb 4> :
4153 : : * # _2 = PHI <255(2), _1(3)>
4154 : : * =>
4155 : : * <bb 4> [local count: 1073741824]:
4156 : : * _2 = .SAT_ADD (x_4(D), y_5(D));
4157 : : *
4158 : : * For signed integer:
4159 : : * x.0_1 = (long unsigned int) x_7(D);
4160 : : * y.1_2 = (long unsigned int) y_8(D);
4161 : : * _3 = x.0_1 + y.1_2;
4162 : : * sum_9 = (int64_t) _3;
4163 : : * _4 = x_7(D) ^ y_8(D);
4164 : : * _5 = x_7(D) ^ sum_9;
4165 : : * _15 = ~_4;
4166 : : * _16 = _5 & _15;
4167 : : * if (_16 < 0)
4168 : : * goto <bb 3>; [41.00%]
4169 : : * else
4170 : : * goto <bb 4>; [59.00%]
4171 : : * _11 = x_7(D) < 0;
4172 : : * _12 = (long int) _11;
4173 : : * _13 = -_12;
4174 : : * _14 = _13 ^ 9223372036854775807;
4175 : : * # _6 = PHI <_14(3), sum_9(2)>
4176 : : * =>
4177 : : * _6 = .SAT_ADD (x_5(D), y_6(D)); [tail call] */
4178 : :
4179 : : static bool
4180 : 4459679 : match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
4181 : : {
4182 : 4459679 : if (gimple_phi_num_args (phi) != 2)
4183 : : return false;
4184 : :
4185 : 3664557 : tree ops[2];
4186 : 3664557 : tree phi_result = gimple_phi_result (phi);
4187 : :
4188 : 3664557 : if (!gimple_unsigned_integer_sat_add (phi_result, ops, NULL)
4189 : 3664557 : && !gimple_signed_integer_sat_add (phi_result, ops, NULL))
4190 : : return false;
4191 : :
4192 : 21 : if (!TYPE_UNSIGNED (TREE_TYPE (ops[0])) && TREE_CODE (ops[1]) == INTEGER_CST)
4193 : 0 : ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
4194 : :
4195 : 21 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_ADD,
4196 : : phi_result, ops[0],
4197 : 21 : ops[1]);
4198 : : }
4199 : :
4200 : : /*
4201 : : * Try to match saturation unsigned sub.
4202 : : * _1 = _4 >= _5;
4203 : : * _3 = _4 - _5;
4204 : : * _6 = _1 ? _3 : 0;
4205 : : * =>
4206 : : * _6 = .SAT_SUB (_4, _5); */
4207 : :
4208 : : static void
4209 : 3315033 : match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
4210 : : {
4211 : 3315033 : tree ops[2];
4212 : 3315033 : tree lhs = gimple_assign_lhs (stmt);
4213 : :
4214 : 3315033 : if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
4215 : 111 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_SUB, lhs,
4216 : : ops[0], ops[1]);
4217 : 3315033 : }
4218 : :
4219 : : /*
4220 : : * Try to match saturation unsigned sub.
4221 : : * <bb 2> [local count: 1073741824]:
4222 : : * if (x_2(D) > y_3(D))
4223 : : * goto <bb 3>; [50.00%]
4224 : : * else
4225 : : * goto <bb 4>; [50.00%]
4226 : : *
4227 : : * <bb 3> [local count: 536870912]:
4228 : : * _4 = x_2(D) - y_3(D);
4229 : : *
4230 : : * <bb 4> [local count: 1073741824]:
4231 : : * # _1 = PHI <0(2), _4(3)>
4232 : : * =>
4233 : : * <bb 4> [local count: 1073741824]:
4234 : : * _1 = .SAT_SUB (x_2(D), y_3(D)); */
4235 : : static bool
4236 : 4459662 : match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
4237 : : {
4238 : 4459662 : if (gimple_phi_num_args (phi) != 2)
4239 : : return false;
4240 : :
4241 : 3664540 : tree ops[2];
4242 : 3664540 : tree phi_result = gimple_phi_result (phi);
4243 : :
4244 : 3664540 : if (!gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
4245 : 3664540 : && !gimple_signed_integer_sat_sub (phi_result, ops, NULL))
4246 : : return false;
4247 : :
4248 : 14 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_SUB,
4249 : : phi_result, ops[0],
4250 : 14 : ops[1]);
4251 : : }
4252 : :
4253 : : /*
4254 : : * Try to match saturation unsigned sub.
4255 : : * uint16_t x_4(D);
4256 : : * uint8_t _6;
4257 : : * overflow_5 = x_4(D) > 255;
4258 : : * _1 = (unsigned char) x_4(D);
4259 : : * _2 = (unsigned char) overflow_5;
4260 : : * _3 = -_2;
4261 : : * _6 = _1 | _3;
4262 : : * =>
4263 : : * _6 = .SAT_TRUNC (x_4(D));
4264 : : * */
4265 : : static void
4266 : 2591530 : match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
4267 : : {
4268 : 2591530 : tree ops[1];
4269 : 2591530 : tree lhs = gimple_assign_lhs (stmt);
4270 : 2591530 : tree type = TREE_TYPE (lhs);
4271 : :
4272 : 2591530 : if (gimple_unsigned_integer_sat_trunc (lhs, ops, NULL)
4273 : 2591630 : && direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4274 : 100 : tree_pair (type, TREE_TYPE (ops[0])),
4275 : : OPTIMIZE_FOR_BOTH))
4276 : : {
4277 : 73 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4278 : 73 : gimple_call_set_lhs (call, lhs);
4279 : 73 : gsi_replace (gsi, call, /* update_eh_info */ true);
4280 : : }
4281 : 2591530 : }
4282 : :
4283 : : /*
4284 : : * Try to match saturation truncate.
4285 : : * Aka:
4286 : : * x.0_1 = (unsigned long) x_4(D);
4287 : : * _2 = x.0_1 + 2147483648;
4288 : : * if (_2 > 4294967295)
4289 : : * goto <bb 4>; [50.00%]
4290 : : * else
4291 : : * goto <bb 3>; [50.00%]
4292 : : * ;; succ: 4
4293 : : * ;; 3
4294 : : *
4295 : : * ;; basic block 3, loop depth 0
4296 : : * ;; pred: 2
4297 : : * trunc_5 = (int32_t) x_4(D);
4298 : : * goto <bb 5>; [100.00%]
4299 : : * ;; succ: 5
4300 : : *
4301 : : * ;; basic block 4, loop depth 0
4302 : : * ;; pred: 2
4303 : : * _7 = x_4(D) < 0;
4304 : : * _8 = (int) _7;
4305 : : * _9 = -_8;
4306 : : * _10 = _9 ^ 2147483647;
4307 : : * ;; succ: 5
4308 : : *
4309 : : * ;; basic block 5, loop depth 0
4310 : : * ;; pred: 3
4311 : : * ;; 4
4312 : : * # _3 = PHI <trunc_5(3), _10(4)>
4313 : : * =>
4314 : : * _6 = .SAT_TRUNC (x_4(D));
4315 : : */
4316 : :
4317 : : static bool
4318 : 4459652 : match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
4319 : : {
4320 : 4459652 : if (gimple_phi_num_args (phi) != 2)
4321 : : return false;
4322 : :
4323 : 3664530 : tree ops[1];
4324 : 3664530 : tree phi_result = gimple_phi_result (phi);
4325 : 3664530 : tree type = TREE_TYPE (phi_result);
4326 : :
4327 : 3664530 : if (!gimple_unsigned_integer_sat_trunc (phi_result, ops, NULL)
4328 : 3664530 : && !gimple_signed_integer_sat_trunc (phi_result, ops, NULL))
4329 : : return false;
4330 : :
4331 : 0 : if (!direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4332 : 0 : tree_pair (type, TREE_TYPE (ops[0])),
4333 : : OPTIMIZE_FOR_BOTH))
4334 : : return false;
4335 : :
4336 : 0 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4337 : 0 : gimple_call_set_lhs (call, phi_result);
4338 : 0 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4339 : :
4340 : 0 : return true;
4341 : : }
4342 : :
4343 : : /* Recognize for unsigned x
4344 : : x = y - z;
4345 : : if (x > y)
4346 : : where there are other uses of x and replace it with
4347 : : _7 = .SUB_OVERFLOW (y, z);
4348 : : x = REALPART_EXPR <_7>;
4349 : : _8 = IMAGPART_EXPR <_7>;
4350 : : if (_8)
4351 : : and similarly for addition.
4352 : :
4353 : : Also recognize:
4354 : : yc = (type) y;
4355 : : zc = (type) z;
4356 : : x = yc + zc;
4357 : : if (x > max)
4358 : : where y and z have unsigned types with maximum max
4359 : : and there are other uses of x and all of those cast x
4360 : : back to that unsigned type and again replace it with
4361 : : _7 = .ADD_OVERFLOW (y, z);
4362 : : _9 = REALPART_EXPR <_7>;
4363 : : _8 = IMAGPART_EXPR <_7>;
4364 : : if (_8)
4365 : : and replace (utype) x with _9.
4366 : : Or with x >> popcount (max) instead of x > max.
4367 : :
4368 : : Also recognize:
4369 : : x = ~z;
4370 : : if (y > x)
4371 : : and replace it with
4372 : : _7 = .ADD_OVERFLOW (y, z);
4373 : : _8 = IMAGPART_EXPR <_7>;
4374 : : if (_8)
4375 : :
4376 : : And also recognize:
4377 : : z = x * y;
4378 : : if (x != 0)
4379 : : goto <bb 3>; [50.00%]
4380 : : else
4381 : : goto <bb 4>; [50.00%]
4382 : :
4383 : : <bb 3> [local count: 536870913]:
4384 : : _2 = z / x;
4385 : : _9 = _2 != y;
4386 : : _10 = (int) _9;
4387 : :
4388 : : <bb 4> [local count: 1073741824]:
4389 : : # iftmp.0_3 = PHI <_10(3), 0(2)>
4390 : : and replace it with
4391 : : _7 = .MUL_OVERFLOW (x, y);
4392 : : z = IMAGPART_EXPR <_7>;
4393 : : _8 = IMAGPART_EXPR <_7>;
4394 : : _9 = _8 != 0;
4395 : : iftmp.0_3 = (int) _9; */
4396 : :
4397 : : static bool
4398 : 3254853 : match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
4399 : : enum tree_code code, bool *cfg_changed)
4400 : : {
4401 : 3254853 : tree lhs = gimple_assign_lhs (stmt);
4402 : 3254853 : tree type = TREE_TYPE (lhs);
4403 : 3254853 : use_operand_p use_p;
4404 : 3254853 : imm_use_iterator iter;
4405 : 3254853 : bool use_seen = false;
4406 : 3254853 : bool ovf_use_seen = false;
4407 : 3254853 : gimple *use_stmt;
4408 : 3254853 : gimple *add_stmt = NULL;
4409 : 3254853 : bool add_first = false;
4410 : 3254853 : gimple *cond_stmt = NULL;
4411 : 3254853 : gimple *cast_stmt = NULL;
4412 : 3254853 : tree cast_lhs = NULL_TREE;
4413 : :
4414 : 3254853 : gcc_checking_assert (code == PLUS_EXPR
4415 : : || code == MINUS_EXPR
4416 : : || code == MULT_EXPR
4417 : : || code == BIT_NOT_EXPR);
4418 : 3254853 : if (!INTEGRAL_TYPE_P (type)
4419 : 2740014 : || !TYPE_UNSIGNED (type)
4420 : 1891073 : || has_zero_uses (lhs)
4421 : 3254853 : || (code != PLUS_EXPR
4422 : 1890904 : && code != MULT_EXPR
4423 : 175715 : && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab,
4424 : 151885 : TYPE_MODE (type)) == CODE_FOR_nothing))
4425 : 1365753 : return false;
4426 : :
4427 : 1889100 : tree rhs1 = gimple_assign_rhs1 (stmt);
4428 : 1889100 : tree rhs2 = gimple_assign_rhs2 (stmt);
4429 : 5111617 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4430 : : {
4431 : 3228629 : use_stmt = USE_STMT (use_p);
4432 : 3228629 : if (is_gimple_debug (use_stmt))
4433 : 476484 : continue;
4434 : :
4435 : 2752145 : tree other = NULL_TREE;
4436 : 2752145 : if (arith_overflow_check_p (stmt, NULL, use_stmt, NULL_TREE, &other))
4437 : : {
4438 : 6604 : if (code == BIT_NOT_EXPR)
4439 : : {
4440 : 187 : gcc_assert (other);
4441 : 187 : if (TREE_CODE (other) != SSA_NAME)
4442 : 0 : return false;
4443 : 187 : if (rhs2 == NULL)
4444 : 187 : rhs2 = other;
4445 : : else
4446 : : return false;
4447 : 187 : cond_stmt = use_stmt;
4448 : : }
4449 : : ovf_use_seen = true;
4450 : : }
4451 : : else
4452 : : {
4453 : 2745541 : use_seen = true;
4454 : 2745541 : if (code == MULT_EXPR
4455 : 2745541 : && cast_stmt == NULL
4456 : 2745541 : && gimple_assign_cast_p (use_stmt))
4457 : : {
4458 : 17351 : cast_lhs = gimple_assign_lhs (use_stmt);
4459 : 34702 : if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
4460 : 16802 : && !TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
4461 : 29880 : && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
4462 : 12529 : == TYPE_PRECISION (TREE_TYPE (lhs))))
4463 : : cast_stmt = use_stmt;
4464 : : else
4465 : : cast_lhs = NULL_TREE;
4466 : : }
4467 : : }
4468 : 2752145 : if (ovf_use_seen && use_seen)
4469 : : break;
4470 : : }
4471 : :
4472 : 1889100 : if (!ovf_use_seen
4473 : 1889100 : && code == MULT_EXPR
4474 : 426257 : && cast_stmt)
4475 : : {
4476 : 12172 : if (TREE_CODE (rhs1) != SSA_NAME
4477 : 12172 : || (TREE_CODE (rhs2) != SSA_NAME && TREE_CODE (rhs2) != INTEGER_CST))
4478 : : return false;
4479 : 27888 : FOR_EACH_IMM_USE_FAST (use_p, iter, cast_lhs)
4480 : : {
4481 : 15716 : use_stmt = USE_STMT (use_p);
4482 : 15716 : if (is_gimple_debug (use_stmt))
4483 : 848 : continue;
4484 : :
4485 : 14868 : if (arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4486 : : NULL_TREE, NULL))
4487 : 15716 : ovf_use_seen = true;
4488 : : }
4489 : : }
4490 : : else
4491 : : {
4492 : : cast_stmt = NULL;
4493 : : cast_lhs = NULL_TREE;
4494 : : }
4495 : :
4496 : 1889100 : tree maxval = NULL_TREE;
4497 : 1889100 : if (!ovf_use_seen
4498 : 13211 : || (code != MULT_EXPR && (code == BIT_NOT_EXPR ? use_seen : !use_seen))
4499 : 6230 : || (code == PLUS_EXPR
4500 : 5960 : && optab_handler (uaddv4_optab,
4501 : 5960 : TYPE_MODE (type)) == CODE_FOR_nothing)
4502 : 1902009 : || (code == MULT_EXPR
4503 : 219 : && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
4504 : 147 : TYPE_MODE (type)) == CODE_FOR_nothing
4505 : 3 : && (use_seen
4506 : 3 : || cast_stmt
4507 : 0 : || !can_mult_highpart_p (TYPE_MODE (type), true))))
4508 : : {
4509 : 1882726 : if (code != PLUS_EXPR)
4510 : : return false;
4511 : 1306730 : if (TREE_CODE (rhs1) != SSA_NAME
4512 : 1306730 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
4513 : : return false;
4514 : 318805 : rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
4515 : 318805 : tree type1 = TREE_TYPE (rhs1);
4516 : 318805 : if (!INTEGRAL_TYPE_P (type1)
4517 : 173333 : || !TYPE_UNSIGNED (type1)
4518 : 41566 : || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
4519 : 336556 : || (TYPE_PRECISION (type1)
4520 : 35502 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
4521 : 308117 : return false;
4522 : 10688 : if (TREE_CODE (rhs2) == INTEGER_CST)
4523 : : {
4524 : 3934 : if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
4525 : 3934 : TYPE_PRECISION (type1),
4526 : 7868 : UNSIGNED), 0))
4527 : : return false;
4528 : 1360 : rhs2 = fold_convert (type1, rhs2);
4529 : : }
4530 : : else
4531 : : {
4532 : 6754 : if (TREE_CODE (rhs2) != SSA_NAME
4533 : 6754 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
4534 : : return false;
4535 : 2336 : rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
4536 : 2336 : tree type2 = TREE_TYPE (rhs2);
4537 : 2336 : if (!INTEGRAL_TYPE_P (type2)
4538 : 1101 : || !TYPE_UNSIGNED (type2)
4539 : 395 : || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
4540 : 2687 : || (TYPE_PRECISION (type2)
4541 : 702 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
4542 : 1998 : return false;
4543 : : }
4544 : 1698 : if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
4545 : : type = type1;
4546 : : else
4547 : 5 : type = TREE_TYPE (rhs2);
4548 : :
4549 : 1698 : if (TREE_CODE (type) != INTEGER_TYPE
4550 : 3394 : || optab_handler (uaddv4_optab,
4551 : 1696 : TYPE_MODE (type)) == CODE_FOR_nothing)
4552 : 2 : return false;
4553 : :
4554 : 1696 : maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
4555 : : UNSIGNED));
4556 : 1696 : ovf_use_seen = false;
4557 : 1696 : use_seen = false;
4558 : 1696 : basic_block use_bb = NULL;
4559 : 1744 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4560 : : {
4561 : 1720 : use_stmt = USE_STMT (use_p);
4562 : 1720 : if (is_gimple_debug (use_stmt))
4563 : 20 : continue;
4564 : :
4565 : 1700 : if (arith_overflow_check_p (stmt, NULL, use_stmt, maxval, NULL))
4566 : : {
4567 : 12 : ovf_use_seen = true;
4568 : 12 : use_bb = gimple_bb (use_stmt);
4569 : : }
4570 : : else
4571 : : {
4572 : 1688 : if (!gimple_assign_cast_p (use_stmt)
4573 : 1688 : || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
4574 : : return false;
4575 : 68 : tree use_lhs = gimple_assign_lhs (use_stmt);
4576 : 136 : if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
4577 : 136 : || (TYPE_PRECISION (TREE_TYPE (use_lhs))
4578 : 68 : > TYPE_PRECISION (type)))
4579 : : return false;
4580 : : use_seen = true;
4581 : : }
4582 : : }
4583 : 24 : if (!ovf_use_seen)
4584 : : return false;
4585 : 12 : if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
4586 : : {
4587 : 2 : if (!use_seen)
4588 : : return false;
4589 : 2 : tree new_rhs1 = make_ssa_name (type);
4590 : 2 : gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
4591 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4592 : 2 : rhs1 = new_rhs1;
4593 : : }
4594 : 10 : else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
4595 : : {
4596 : 2 : if (!use_seen)
4597 : : return false;
4598 : 2 : tree new_rhs2 = make_ssa_name (type);
4599 : 2 : gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
4600 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4601 : 2 : rhs2 = new_rhs2;
4602 : : }
4603 : 8 : else if (!use_seen)
4604 : : {
4605 : : /* If there are no uses of the wider addition, check if
4606 : : forwprop has not created a narrower addition.
4607 : : Require it to be in the same bb as the overflow check. */
4608 : 10 : FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
4609 : : {
4610 : 10 : use_stmt = USE_STMT (use_p);
4611 : 10 : if (is_gimple_debug (use_stmt))
4612 : 0 : continue;
4613 : :
4614 : 10 : if (use_stmt == stmt)
4615 : 0 : continue;
4616 : :
4617 : 10 : if (!is_gimple_assign (use_stmt)
4618 : 10 : || gimple_bb (use_stmt) != use_bb
4619 : 20 : || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
4620 : 2 : continue;
4621 : :
4622 : 8 : if (gimple_assign_rhs1 (use_stmt) == rhs1)
4623 : : {
4624 : 8 : if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
4625 : : rhs2, 0))
4626 : 0 : continue;
4627 : : }
4628 : 0 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
4629 : : {
4630 : 0 : if (gimple_assign_rhs1 (use_stmt) != rhs2)
4631 : 0 : continue;
4632 : : }
4633 : : else
4634 : 0 : continue;
4635 : :
4636 : 8 : add_stmt = use_stmt;
4637 : 8 : break;
4638 : : }
4639 : 8 : if (add_stmt == NULL)
4640 : : return false;
4641 : :
4642 : : /* If stmt and add_stmt are in the same bb, we need to find out
4643 : : which one is earlier. If they are in different bbs, we've
4644 : : checked add_stmt is in the same bb as one of the uses of the
4645 : : stmt lhs, so stmt needs to dominate add_stmt too. */
4646 : 8 : if (gimple_bb (stmt) == gimple_bb (add_stmt))
4647 : : {
4648 : 8 : gimple_stmt_iterator gsif = *gsi;
4649 : 8 : gimple_stmt_iterator gsib = *gsi;
4650 : 8 : int i;
4651 : : /* Search both forward and backward from stmt and have a small
4652 : : upper bound. */
4653 : 20 : for (i = 0; i < 128; i++)
4654 : : {
4655 : 20 : if (!gsi_end_p (gsib))
4656 : : {
4657 : 18 : gsi_prev_nondebug (&gsib);
4658 : 18 : if (gsi_stmt (gsib) == add_stmt)
4659 : : {
4660 : : add_first = true;
4661 : : break;
4662 : : }
4663 : : }
4664 : 2 : else if (gsi_end_p (gsif))
4665 : : break;
4666 : 18 : if (!gsi_end_p (gsif))
4667 : : {
4668 : 18 : gsi_next_nondebug (&gsif);
4669 : 18 : if (gsi_stmt (gsif) == add_stmt)
4670 : : break;
4671 : : }
4672 : : }
4673 : 8 : if (i == 128)
4674 : 0 : return false;
4675 : 8 : if (add_first)
4676 : 2 : *gsi = gsi_for_stmt (add_stmt);
4677 : : }
4678 : : }
4679 : : }
4680 : :
4681 : 6386 : if (code == BIT_NOT_EXPR)
4682 : 170 : *gsi = gsi_for_stmt (cond_stmt);
4683 : :
4684 : 6386 : auto_vec<gimple *, 8> mul_stmts;
4685 : 6386 : if (code == MULT_EXPR && cast_stmt)
4686 : : {
4687 : 75 : type = TREE_TYPE (cast_lhs);
4688 : 75 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
4689 : 75 : if (gimple_assign_cast_p (g)
4690 : 38 : && useless_type_conversion_p (type,
4691 : 38 : TREE_TYPE (gimple_assign_rhs1 (g)))
4692 : 113 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4693 : : rhs1 = gimple_assign_rhs1 (g);
4694 : : else
4695 : : {
4696 : 37 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs1);
4697 : 37 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4698 : 37 : rhs1 = gimple_assign_lhs (g);
4699 : 37 : mul_stmts.quick_push (g);
4700 : : }
4701 : 75 : if (TREE_CODE (rhs2) == INTEGER_CST)
4702 : 32 : rhs2 = fold_convert (type, rhs2);
4703 : : else
4704 : : {
4705 : 43 : g = SSA_NAME_DEF_STMT (rhs2);
4706 : 43 : if (gimple_assign_cast_p (g)
4707 : 22 : && useless_type_conversion_p (type,
4708 : 22 : TREE_TYPE (gimple_assign_rhs1 (g)))
4709 : 65 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4710 : : rhs2 = gimple_assign_rhs1 (g);
4711 : : else
4712 : : {
4713 : 21 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs2);
4714 : 21 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4715 : 21 : rhs2 = gimple_assign_lhs (g);
4716 : 21 : mul_stmts.quick_push (g);
4717 : : }
4718 : : }
4719 : : }
4720 : 6386 : tree ctype = build_complex_type (type);
4721 : 12628 : gcall *g = gimple_build_call_internal (code == MULT_EXPR
4722 : : ? IFN_MUL_OVERFLOW
4723 : : : code != MINUS_EXPR
4724 : 6242 : ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
4725 : : 2, rhs1, rhs2);
4726 : 6386 : tree ctmp = make_ssa_name (ctype);
4727 : 6386 : gimple_call_set_lhs (g, ctmp);
4728 : 6386 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4729 : 6386 : tree new_lhs = (maxval || cast_stmt) ? make_ssa_name (type) : lhs;
4730 : 6386 : gassign *g2;
4731 : 6386 : if (code != BIT_NOT_EXPR)
4732 : : {
4733 : 6216 : g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
4734 : : build1 (REALPART_EXPR, type, ctmp));
4735 : 6216 : if (maxval || cast_stmt)
4736 : : {
4737 : 87 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4738 : 87 : if (add_first)
4739 : 2 : *gsi = gsi_for_stmt (stmt);
4740 : : }
4741 : : else
4742 : 6129 : gsi_replace (gsi, g2, true);
4743 : 6216 : if (code == MULT_EXPR)
4744 : : {
4745 : 144 : mul_stmts.quick_push (g);
4746 : 144 : mul_stmts.quick_push (g2);
4747 : 144 : if (cast_stmt)
4748 : : {
4749 : 75 : g2 = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
4750 : 75 : gsi_replace (gsi, g2, true);
4751 : 75 : mul_stmts.quick_push (g2);
4752 : : }
4753 : : }
4754 : : }
4755 : 6386 : tree ovf = make_ssa_name (type);
4756 : 6386 : g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
4757 : : build1 (IMAGPART_EXPR, type, ctmp));
4758 : 6386 : if (code != BIT_NOT_EXPR)
4759 : 6216 : gsi_insert_after (gsi, g2, GSI_NEW_STMT);
4760 : : else
4761 : 170 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4762 : 6386 : if (code == MULT_EXPR)
4763 : 144 : mul_stmts.quick_push (g2);
4764 : :
4765 : 32817 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
4766 : : {
4767 : 20120 : if (is_gimple_debug (use_stmt))
4768 : 4326 : continue;
4769 : :
4770 : 15794 : gimple *orig_use_stmt = use_stmt;
4771 : 15794 : int ovf_use = arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4772 : : maxval, NULL);
4773 : 15794 : if (ovf_use == 0)
4774 : : {
4775 : 9378 : gcc_assert (code != BIT_NOT_EXPR);
4776 : 9378 : if (maxval)
4777 : : {
4778 : 4 : tree use_lhs = gimple_assign_lhs (use_stmt);
4779 : 4 : gimple_assign_set_rhs1 (use_stmt, new_lhs);
4780 : 4 : if (useless_type_conversion_p (TREE_TYPE (use_lhs),
4781 : 4 : TREE_TYPE (new_lhs)))
4782 : 4 : gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
4783 : 4 : update_stmt (use_stmt);
4784 : : }
4785 : 9378 : continue;
4786 : 9378 : }
4787 : 6416 : if (gimple_code (use_stmt) == GIMPLE_COND)
4788 : : {
4789 : 4287 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4790 : 4287 : gimple_cond_set_lhs (cond_stmt, ovf);
4791 : 4287 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4792 : 4439 : gimple_cond_set_code (cond_stmt, ovf_use == 1 ? NE_EXPR : EQ_EXPR);
4793 : : }
4794 : : else
4795 : : {
4796 : 2129 : gcc_checking_assert (is_gimple_assign (use_stmt));
4797 : 2129 : if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
4798 : : {
4799 : 2129 : if (gimple_assign_rhs_code (use_stmt) == RSHIFT_EXPR)
4800 : : {
4801 : 6 : g2 = gimple_build_assign (make_ssa_name (boolean_type_node),
4802 : : ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4803 : : ovf, build_int_cst (type, 0));
4804 : 6 : gimple_stmt_iterator gsiu = gsi_for_stmt (use_stmt);
4805 : 6 : gsi_insert_before (&gsiu, g2, GSI_SAME_STMT);
4806 : 6 : gimple_assign_set_rhs_with_ops (&gsiu, NOP_EXPR,
4807 : : gimple_assign_lhs (g2));
4808 : 6 : update_stmt (use_stmt);
4809 : 6 : use_operand_p use;
4810 : 6 : single_imm_use (gimple_assign_lhs (use_stmt), &use,
4811 : : &use_stmt);
4812 : 6 : if (gimple_code (use_stmt) == GIMPLE_COND)
4813 : : {
4814 : 0 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4815 : 0 : gimple_cond_set_lhs (cond_stmt, ovf);
4816 : 0 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4817 : : }
4818 : : else
4819 : : {
4820 : 6 : gcc_checking_assert (is_gimple_assign (use_stmt));
4821 : 6 : if (gimple_assign_rhs_class (use_stmt)
4822 : : == GIMPLE_BINARY_RHS)
4823 : : {
4824 : 0 : gimple_assign_set_rhs1 (use_stmt, ovf);
4825 : 0 : gimple_assign_set_rhs2 (use_stmt,
4826 : : build_int_cst (type, 0));
4827 : : }
4828 : 6 : else if (gimple_assign_cast_p (use_stmt))
4829 : 6 : gimple_assign_set_rhs1 (use_stmt, ovf);
4830 : : else
4831 : : {
4832 : 0 : tree_code sc = gimple_assign_rhs_code (use_stmt);
4833 : 0 : gcc_checking_assert (sc == COND_EXPR);
4834 : 0 : tree cond = gimple_assign_rhs1 (use_stmt);
4835 : 0 : cond = build2 (TREE_CODE (cond),
4836 : : boolean_type_node, ovf,
4837 : : build_int_cst (type, 0));
4838 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4839 : : }
4840 : : }
4841 : 6 : update_stmt (use_stmt);
4842 : 6 : gsi_remove (&gsiu, true);
4843 : 6 : gsiu = gsi_for_stmt (g2);
4844 : 6 : gsi_remove (&gsiu, true);
4845 : 6 : continue;
4846 : 6 : }
4847 : : else
4848 : : {
4849 : 2123 : gimple_assign_set_rhs1 (use_stmt, ovf);
4850 : 2123 : gimple_assign_set_rhs2 (use_stmt, build_int_cst (type, 0));
4851 : 2272 : gimple_assign_set_rhs_code (use_stmt,
4852 : : ovf_use == 1
4853 : : ? NE_EXPR : EQ_EXPR);
4854 : : }
4855 : : }
4856 : : else
4857 : : {
4858 : 0 : gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
4859 : : == COND_EXPR);
4860 : 0 : tree cond = build2 (ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4861 : : boolean_type_node, ovf,
4862 : : build_int_cst (type, 0));
4863 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4864 : : }
4865 : : }
4866 : 6410 : update_stmt (use_stmt);
4867 : 6410 : if (code == MULT_EXPR && use_stmt != orig_use_stmt)
4868 : : {
4869 : 144 : gimple_stmt_iterator gsi2 = gsi_for_stmt (orig_use_stmt);
4870 : 144 : maybe_optimize_guarding_check (mul_stmts, use_stmt, orig_use_stmt,
4871 : : cfg_changed);
4872 : 144 : use_operand_p use;
4873 : 144 : gimple *cast_stmt;
4874 : 144 : if (single_imm_use (gimple_assign_lhs (orig_use_stmt), &use,
4875 : : &cast_stmt)
4876 : 144 : && gimple_assign_cast_p (cast_stmt))
4877 : : {
4878 : 2 : gimple_stmt_iterator gsi3 = gsi_for_stmt (cast_stmt);
4879 : 2 : gsi_remove (&gsi3, true);
4880 : 2 : release_ssa_name (gimple_assign_lhs (cast_stmt));
4881 : : }
4882 : 144 : gsi_remove (&gsi2, true);
4883 : 144 : release_ssa_name (gimple_assign_lhs (orig_use_stmt));
4884 : : }
4885 : 6386 : }
4886 : 6386 : if (maxval)
4887 : : {
4888 : 12 : gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
4889 : 12 : gsi_remove (&gsi2, true);
4890 : 12 : if (add_stmt)
4891 : : {
4892 : 8 : gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
4893 : : new_lhs);
4894 : 8 : gsi2 = gsi_for_stmt (add_stmt);
4895 : 8 : gsi_replace (&gsi2, g, true);
4896 : : }
4897 : : }
4898 : 6374 : else if (code == BIT_NOT_EXPR)
4899 : : {
4900 : 170 : *gsi = gsi_for_stmt (stmt);
4901 : 170 : gsi_remove (gsi, true);
4902 : 170 : release_ssa_name (lhs);
4903 : 170 : return true;
4904 : : }
4905 : : return false;
4906 : 6386 : }
4907 : :
4908 : : /* Helper of match_uaddc_usubc. Look through an integral cast
4909 : : which should preserve [0, 1] range value (unless source has
4910 : : 1-bit signed type) and the cast has single use. */
4911 : :
4912 : : static gimple *
4913 : 2003214 : uaddc_cast (gimple *g)
4914 : : {
4915 : 2003214 : if (!gimple_assign_cast_p (g))
4916 : : return g;
4917 : 474953 : tree op = gimple_assign_rhs1 (g);
4918 : 474953 : if (TREE_CODE (op) == SSA_NAME
4919 : 399146 : && INTEGRAL_TYPE_P (TREE_TYPE (op))
4920 : 281776 : && (TYPE_PRECISION (TREE_TYPE (op)) > 1
4921 : 7843 : || TYPE_UNSIGNED (TREE_TYPE (op)))
4922 : 756729 : && has_single_use (gimple_assign_lhs (g)))
4923 : 181862 : return SSA_NAME_DEF_STMT (op);
4924 : : return g;
4925 : : }
4926 : :
4927 : : /* Helper of match_uaddc_usubc. Look through a NE_EXPR
4928 : : comparison with 0 which also preserves [0, 1] value range. */
4929 : :
4930 : : static gimple *
4931 : 2003373 : uaddc_ne0 (gimple *g)
4932 : : {
4933 : 2003373 : if (is_gimple_assign (g)
4934 : 1229268 : && gimple_assign_rhs_code (g) == NE_EXPR
4935 : 55164 : && integer_zerop (gimple_assign_rhs2 (g))
4936 : 5762 : && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
4937 : 2009135 : && has_single_use (gimple_assign_lhs (g)))
4938 : 5557 : return SSA_NAME_DEF_STMT (gimple_assign_rhs1 (g));
4939 : : return g;
4940 : : }
4941 : :
4942 : : /* Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
4943 : : operand. */
4944 : :
4945 : : static bool
4946 : 2004204 : uaddc_is_cplxpart (gimple *g, tree_code part)
4947 : : {
4948 : 2004204 : return (is_gimple_assign (g)
4949 : 1228195 : && gimple_assign_rhs_code (g) == part
4950 : 2006457 : && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (g), 0)) == SSA_NAME);
4951 : : }
4952 : :
4953 : : /* Try to match e.g.
4954 : : _29 = .ADD_OVERFLOW (_3, _4);
4955 : : _30 = REALPART_EXPR <_29>;
4956 : : _31 = IMAGPART_EXPR <_29>;
4957 : : _32 = .ADD_OVERFLOW (_30, _38);
4958 : : _33 = REALPART_EXPR <_32>;
4959 : : _34 = IMAGPART_EXPR <_32>;
4960 : : _35 = _31 + _34;
4961 : : as
4962 : : _36 = .UADDC (_3, _4, _38);
4963 : : _33 = REALPART_EXPR <_36>;
4964 : : _35 = IMAGPART_EXPR <_36>;
4965 : : or
4966 : : _22 = .SUB_OVERFLOW (_6, _5);
4967 : : _23 = REALPART_EXPR <_22>;
4968 : : _24 = IMAGPART_EXPR <_22>;
4969 : : _25 = .SUB_OVERFLOW (_23, _37);
4970 : : _26 = REALPART_EXPR <_25>;
4971 : : _27 = IMAGPART_EXPR <_25>;
4972 : : _28 = _24 | _27;
4973 : : as
4974 : : _29 = .USUBC (_6, _5, _37);
4975 : : _26 = REALPART_EXPR <_29>;
4976 : : _288 = IMAGPART_EXPR <_29>;
4977 : : provided _38 or _37 above have [0, 1] range
4978 : : and _3, _4 and _30 or _6, _5 and _23 are unsigned
4979 : : integral types with the same precision. Whether + or | or ^ is
4980 : : used on the IMAGPART_EXPR results doesn't matter, with one of
4981 : : added or subtracted operands in [0, 1] range at most one
4982 : : .ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow. */
4983 : :
4984 : : static bool
4985 : 2746993 : match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
4986 : : {
4987 : 2746993 : tree rhs[4];
4988 : 2746993 : rhs[0] = gimple_assign_rhs1 (stmt);
4989 : 2746993 : rhs[1] = gimple_assign_rhs2 (stmt);
4990 : 2746993 : rhs[2] = NULL_TREE;
4991 : 2746993 : rhs[3] = NULL_TREE;
4992 : 2746993 : tree type = TREE_TYPE (rhs[0]);
4993 : 2746993 : if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))
4994 : : return false;
4995 : :
4996 : 1606676 : auto_vec<gimple *, 2> temp_stmts;
4997 : 1606676 : if (code != BIT_IOR_EXPR && code != BIT_XOR_EXPR)
4998 : : {
4999 : : /* If overflow flag is ignored on the MSB limb, we can end up with
5000 : : the most significant limb handled as r = op1 + op2 + ovf1 + ovf2;
5001 : : or r = op1 - op2 - ovf1 - ovf2; or various equivalent expressions
5002 : : thereof. Handle those like the ovf = ovf1 + ovf2; case to recognize
5003 : : the limb below the MSB, but also create another .UADDC/.USUBC call
5004 : : for the last limb.
5005 : :
5006 : : First look through assignments with the same rhs code as CODE,
5007 : : with the exception that subtraction of a constant is canonicalized
5008 : : into addition of its negation. rhs[0] will be minuend for
5009 : : subtractions and one of addends for addition, all other assigned
5010 : : rhs[i] operands will be subtrahends or other addends. */
5011 : 1475207 : while (TREE_CODE (rhs[0]) == SSA_NAME && !rhs[3])
5012 : : {
5013 : 1451930 : gimple *g = SSA_NAME_DEF_STMT (rhs[0]);
5014 : 1451930 : if (has_single_use (rhs[0])
5015 : 504289 : && is_gimple_assign (g)
5016 : 1897715 : && (gimple_assign_rhs_code (g) == code
5017 : 418646 : || (code == MINUS_EXPR
5018 : 55714 : && gimple_assign_rhs_code (g) == PLUS_EXPR
5019 : 17305 : && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST)))
5020 : : {
5021 : 40508 : tree r2 = gimple_assign_rhs2 (g);
5022 : 40508 : if (gimple_assign_rhs_code (g) != code)
5023 : : {
5024 : 13369 : r2 = const_unop (NEGATE_EXPR, TREE_TYPE (r2), r2);
5025 : 13369 : if (!r2)
5026 : : break;
5027 : : }
5028 : 40508 : rhs[0] = gimple_assign_rhs1 (g);
5029 : 40508 : tree &r = rhs[2] ? rhs[3] : rhs[2];
5030 : 40508 : r = r2;
5031 : 40508 : temp_stmts.quick_push (g);
5032 : : }
5033 : : else
5034 : : break;
5035 : : }
5036 : 4304097 : for (int i = 1; i <= 2; ++i)
5037 : 2917224 : while (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME && !rhs[3])
5038 : : {
5039 : 515490 : gimple *g = SSA_NAME_DEF_STMT (rhs[i]);
5040 : 515490 : if (has_single_use (rhs[i])
5041 : 275644 : && is_gimple_assign (g)
5042 : 774117 : && gimple_assign_rhs_code (g) == PLUS_EXPR)
5043 : : {
5044 : 47826 : rhs[i] = gimple_assign_rhs1 (g);
5045 : 47826 : if (rhs[2])
5046 : 9890 : rhs[3] = gimple_assign_rhs2 (g);
5047 : : else
5048 : 37936 : rhs[2] = gimple_assign_rhs2 (g);
5049 : 47826 : temp_stmts.quick_push (g);
5050 : : }
5051 : : else
5052 : : break;
5053 : : }
5054 : : /* If there are just 3 addends or one minuend and two subtrahends,
5055 : : check for UADDC or USUBC being pattern recognized earlier.
5056 : : Say r = op1 + op2 + ovf1 + ovf2; where the (ovf1 + ovf2) part
5057 : : got pattern matched earlier as __imag__ .UADDC (arg1, arg2, arg3)
5058 : : etc. */
5059 : 1434699 : if (rhs[2] && !rhs[3])
5060 : : {
5061 : 305921 : for (int i = (code == MINUS_EXPR ? 1 : 0); i < 3; ++i)
5062 : 177792 : if (TREE_CODE (rhs[i]) == SSA_NAME)
5063 : : {
5064 : 139038 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5065 : 139038 : im = uaddc_ne0 (im);
5066 : 139038 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5067 : : {
5068 : : /* We found one of the 3 addends or 2 subtrahends to be
5069 : : __imag__ of something, verify it is .UADDC/.USUBC. */
5070 : 215 : tree rhs1 = gimple_assign_rhs1 (im);
5071 : 215 : gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
5072 : 215 : tree ovf_lhs = NULL_TREE;
5073 : 215 : tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
5074 : 235 : if (gimple_call_internal_p (ovf, code == PLUS_EXPR
5075 : : ? IFN_ADD_OVERFLOW
5076 : : : IFN_SUB_OVERFLOW))
5077 : : {
5078 : : /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
5079 : : This is for the case of 2 chained .UADDC/.USUBC,
5080 : : where the first one uses 0 carry-in and the second
5081 : : one ignores the carry-out.
5082 : : So, something like:
5083 : : _16 = .ADD_OVERFLOW (_1, _2);
5084 : : _17 = REALPART_EXPR <_16>;
5085 : : _18 = IMAGPART_EXPR <_16>;
5086 : : _15 = _3 + _4;
5087 : : _12 = _15 + _18;
5088 : : where the first 3 statements come from the lower
5089 : : limb addition and the last 2 from the higher limb
5090 : : which ignores carry-out. */
5091 : 197 : ovf_lhs = gimple_call_lhs (ovf);
5092 : 197 : tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
5093 : 197 : ovf_arg1 = gimple_call_arg (ovf, 0);
5094 : 197 : ovf_arg2 = gimple_call_arg (ovf, 1);
5095 : : /* In that case we need to punt if the types don't
5096 : : mismatch. */
5097 : 197 : if (!types_compatible_p (type, ovf_lhs_type)
5098 : 197 : || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
5099 : 390 : || !types_compatible_p (type,
5100 : 193 : TREE_TYPE (ovf_arg2)))
5101 : : ovf_lhs = NULL_TREE;
5102 : : else
5103 : : {
5104 : 479 : for (int i = (code == PLUS_EXPR ? 1 : 0);
5105 : 479 : i >= 0; --i)
5106 : : {
5107 : 339 : tree r = gimple_call_arg (ovf, i);
5108 : 339 : if (TREE_CODE (r) != SSA_NAME)
5109 : 0 : continue;
5110 : 339 : if (uaddc_is_cplxpart (SSA_NAME_DEF_STMT (r),
5111 : : REALPART_EXPR))
5112 : : {
5113 : : /* Punt if one of the args which isn't
5114 : : subtracted isn't __real__; that could
5115 : : then prevent better match later.
5116 : : Consider:
5117 : : _3 = .ADD_OVERFLOW (_1, _2);
5118 : : _4 = REALPART_EXPR <_3>;
5119 : : _5 = IMAGPART_EXPR <_3>;
5120 : : _7 = .ADD_OVERFLOW (_4, _6);
5121 : : _8 = REALPART_EXPR <_7>;
5122 : : _9 = IMAGPART_EXPR <_7>;
5123 : : _12 = _10 + _11;
5124 : : _13 = _12 + _9;
5125 : : _14 = _13 + _5;
5126 : : We want to match this when called on
5127 : : the last stmt as a pair of .UADDC calls,
5128 : : but without this check we could turn
5129 : : that prematurely on _13 = _12 + _9;
5130 : : stmt into .UADDC with 0 carry-in just
5131 : : on the second .ADD_OVERFLOW call and
5132 : : another replacing the _12 and _13
5133 : : additions. */
5134 : : ovf_lhs = NULL_TREE;
5135 : : break;
5136 : : }
5137 : : }
5138 : : }
5139 : 190 : if (ovf_lhs)
5140 : : {
5141 : 140 : use_operand_p use_p;
5142 : 140 : imm_use_iterator iter;
5143 : 140 : tree re_lhs = NULL_TREE;
5144 : 420 : FOR_EACH_IMM_USE_FAST (use_p, iter, ovf_lhs)
5145 : : {
5146 : 280 : gimple *use_stmt = USE_STMT (use_p);
5147 : 280 : if (is_gimple_debug (use_stmt))
5148 : 0 : continue;
5149 : 280 : if (use_stmt == im)
5150 : 140 : continue;
5151 : 140 : if (!uaddc_is_cplxpart (use_stmt,
5152 : : REALPART_EXPR))
5153 : : {
5154 : : ovf_lhs = NULL_TREE;
5155 : : break;
5156 : : }
5157 : 140 : re_lhs = gimple_assign_lhs (use_stmt);
5158 : : }
5159 : 140 : if (ovf_lhs && re_lhs)
5160 : : {
5161 : 362 : FOR_EACH_IMM_USE_FAST (use_p, iter, re_lhs)
5162 : : {
5163 : 281 : gimple *use_stmt = USE_STMT (use_p);
5164 : 281 : if (is_gimple_debug (use_stmt))
5165 : 103 : continue;
5166 : 178 : internal_fn ifn
5167 : 178 : = gimple_call_internal_fn (ovf);
5168 : : /* Punt if the __real__ of lhs is used
5169 : : in the same .*_OVERFLOW call.
5170 : : Consider:
5171 : : _3 = .ADD_OVERFLOW (_1, _2);
5172 : : _4 = REALPART_EXPR <_3>;
5173 : : _5 = IMAGPART_EXPR <_3>;
5174 : : _7 = .ADD_OVERFLOW (_4, _6);
5175 : : _8 = REALPART_EXPR <_7>;
5176 : : _9 = IMAGPART_EXPR <_7>;
5177 : : _12 = _10 + _11;
5178 : : _13 = _12 + _5;
5179 : : _14 = _13 + _9;
5180 : : We want to match this when called on
5181 : : the last stmt as a pair of .UADDC calls,
5182 : : but without this check we could turn
5183 : : that prematurely on _13 = _12 + _5;
5184 : : stmt into .UADDC with 0 carry-in just
5185 : : on the first .ADD_OVERFLOW call and
5186 : : another replacing the _12 and _13
5187 : : additions. */
5188 : 178 : if (gimple_call_internal_p (use_stmt, ifn))
5189 : : {
5190 : : ovf_lhs = NULL_TREE;
5191 : : break;
5192 : : }
5193 : : }
5194 : : }
5195 : : }
5196 : : }
5197 : 140 : if ((ovf_lhs
5198 : 143 : || gimple_call_internal_p (ovf,
5199 : : code == PLUS_EXPR
5200 : : ? IFN_UADDC : IFN_USUBC))
5201 : 241 : && (optab_handler (code == PLUS_EXPR
5202 : : ? uaddc5_optab : usubc5_optab,
5203 : 87 : TYPE_MODE (type))
5204 : : != CODE_FOR_nothing))
5205 : : {
5206 : : /* And in that case build another .UADDC/.USUBC
5207 : : call for the most significand limb addition.
5208 : : Overflow bit is ignored here. */
5209 : 63 : if (i != 2)
5210 : 63 : std::swap (rhs[i], rhs[2]);
5211 : 63 : gimple *g
5212 : 77 : = gimple_build_call_internal (code == PLUS_EXPR
5213 : : ? IFN_UADDC
5214 : : : IFN_USUBC,
5215 : : 3, rhs[0], rhs[1],
5216 : : rhs[2]);
5217 : 63 : tree nlhs = make_ssa_name (build_complex_type (type));
5218 : 63 : gimple_call_set_lhs (g, nlhs);
5219 : 63 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5220 : 63 : tree ilhs = gimple_assign_lhs (stmt);
5221 : 63 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5222 : : build1 (REALPART_EXPR,
5223 : 63 : TREE_TYPE (ilhs),
5224 : : nlhs));
5225 : 63 : gsi_replace (gsi, g, true);
5226 : : /* And if it is initialized from result of __imag__
5227 : : of .{ADD,SUB}_OVERFLOW call, replace that
5228 : : call with .U{ADD,SUB}C call with the same arguments,
5229 : : just 0 added as third argument. This isn't strictly
5230 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5231 : : produce the same result, but may result in better
5232 : : generated code on some targets where the backend can
5233 : : better prepare in how the result will be used. */
5234 : 63 : if (ovf_lhs)
5235 : : {
5236 : 57 : tree zero = build_zero_cst (type);
5237 : 57 : g = gimple_build_call_internal (code == PLUS_EXPR
5238 : : ? IFN_UADDC
5239 : : : IFN_USUBC,
5240 : : 3, ovf_arg1,
5241 : : ovf_arg2, zero);
5242 : 57 : gimple_call_set_lhs (g, ovf_lhs);
5243 : 57 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf);
5244 : 57 : gsi_replace (&gsi2, g, true);
5245 : : }
5246 : 63 : return true;
5247 : : }
5248 : : }
5249 : : }
5250 : : return false;
5251 : : }
5252 : 1370603 : if (code == MINUS_EXPR && !rhs[2])
5253 : : return false;
5254 : 251 : if (code == MINUS_EXPR)
5255 : : /* Code below expects rhs[0] and rhs[1] to have the IMAGPART_EXPRs.
5256 : : So, for MINUS_EXPR swap the single added rhs operand (others are
5257 : : subtracted) to rhs[3]. */
5258 : 251 : std::swap (rhs[0], rhs[3]);
5259 : : }
5260 : : /* Walk from both operands of STMT (for +/- even sometimes from
5261 : : all the 4 addends or 3 subtrahends), see through casts and != 0
5262 : : statements which would preserve [0, 1] range of values and
5263 : : check which is initialized from __imag__. */
5264 : 7145078 : gimple *im1 = NULL, *im2 = NULL;
5265 : 14289154 : for (int i = 0; i < (code == MINUS_EXPR ? 3 : 4); i++)
5266 : 5716175 : if (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME)
5267 : : {
5268 : 1864084 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5269 : 1864084 : im = uaddc_ne0 (im);
5270 : 1864084 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5271 : : {
5272 : 1520 : if (im1 == NULL)
5273 : : {
5274 : 1128 : im1 = im;
5275 : 1128 : if (i != 0)
5276 : 335 : std::swap (rhs[0], rhs[i]);
5277 : : }
5278 : : else
5279 : : {
5280 : 392 : im2 = im;
5281 : 392 : if (i != 1)
5282 : 22 : std::swap (rhs[1], rhs[i]);
5283 : : break;
5284 : : }
5285 : : }
5286 : : }
5287 : : /* If we don't find at least two, punt. */
5288 : 1429295 : if (!im2)
5289 : : return false;
5290 : : /* Check they are __imag__ of .ADD_OVERFLOW or .SUB_OVERFLOW call results,
5291 : : either both .ADD_OVERFLOW or both .SUB_OVERFLOW and that we have
5292 : : uaddc5/usubc5 named pattern for the corresponding mode. */
5293 : 392 : gimple *ovf1
5294 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im1), 0));
5295 : 392 : gimple *ovf2
5296 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im2), 0));
5297 : 392 : internal_fn ifn;
5298 : 392 : if (!is_gimple_call (ovf1)
5299 : 392 : || !gimple_call_internal_p (ovf1)
5300 : 392 : || ((ifn = gimple_call_internal_fn (ovf1)) != IFN_ADD_OVERFLOW
5301 : 59 : && ifn != IFN_SUB_OVERFLOW)
5302 : 369 : || !gimple_call_internal_p (ovf2, ifn)
5303 : 397 : || optab_handler (ifn == IFN_ADD_OVERFLOW ? uaddc5_optab : usubc5_optab,
5304 : 365 : TYPE_MODE (type)) == CODE_FOR_nothing
5305 : 485 : || (rhs[2]
5306 : 17 : && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
5307 : 15 : TYPE_MODE (type)) == CODE_FOR_nothing))
5308 : 299 : return false;
5309 : 93 : tree arg1, arg2, arg3 = NULL_TREE;
5310 : 93 : gimple *re1 = NULL, *re2 = NULL;
5311 : : /* On one of the two calls, one of the .ADD_OVERFLOW/.SUB_OVERFLOW arguments
5312 : : should be initialized from __real__ of the other of the two calls.
5313 : : Though, for .SUB_OVERFLOW, it has to be the first argument, not the
5314 : : second one. */
5315 : 340 : for (int i = (ifn == IFN_ADD_OVERFLOW ? 1 : 0); i >= 0; --i)
5316 : 349 : for (gimple *ovf = ovf1; ovf; ovf = (ovf == ovf1 ? ovf2 : NULL))
5317 : : {
5318 : 288 : tree arg = gimple_call_arg (ovf, i);
5319 : 288 : if (TREE_CODE (arg) != SSA_NAME)
5320 : 2 : continue;
5321 : 286 : re1 = SSA_NAME_DEF_STMT (arg);
5322 : 286 : if (uaddc_is_cplxpart (re1, REALPART_EXPR)
5323 : 379 : && (SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (re1), 0))
5324 : 93 : == (ovf == ovf1 ? ovf2 : ovf1)))
5325 : : {
5326 : 93 : if (ovf == ovf1)
5327 : : {
5328 : : /* Make sure ovf2 is the .*_OVERFLOW call with argument
5329 : : initialized from __real__ of ovf1. */
5330 : 20 : std::swap (rhs[0], rhs[1]);
5331 : 20 : std::swap (im1, im2);
5332 : 20 : std::swap (ovf1, ovf2);
5333 : : }
5334 : 93 : arg3 = gimple_call_arg (ovf, 1 - i);
5335 : 93 : i = -1;
5336 : 93 : break;
5337 : : }
5338 : : }
5339 : 93 : if (!arg3)
5340 : : return false;
5341 : 93 : arg1 = gimple_call_arg (ovf1, 0);
5342 : 93 : arg2 = gimple_call_arg (ovf1, 1);
5343 : 93 : if (!types_compatible_p (type, TREE_TYPE (arg1)))
5344 : : return false;
5345 : 93 : int kind[2] = { 0, 0 };
5346 : 93 : tree arg_im[2] = { NULL_TREE, NULL_TREE };
5347 : : /* At least one of arg2 and arg3 should have type compatible
5348 : : with arg1/rhs[0], and the other one should have value in [0, 1]
5349 : : range. If both are in [0, 1] range and type compatible with
5350 : : arg1/rhs[0], try harder to find after looking through casts,
5351 : : != 0 comparisons which one is initialized to __imag__ of
5352 : : .{ADD,SUB}_OVERFLOW or .U{ADD,SUB}C call results. */
5353 : 279 : for (int i = 0; i < 2; ++i)
5354 : : {
5355 : 186 : tree arg = i == 0 ? arg2 : arg3;
5356 : 186 : if (types_compatible_p (type, TREE_TYPE (arg)))
5357 : 161 : kind[i] = 1;
5358 : 372 : if (!INTEGRAL_TYPE_P (TREE_TYPE (arg))
5359 : 372 : || (TYPE_PRECISION (TREE_TYPE (arg)) == 1
5360 : 25 : && !TYPE_UNSIGNED (TREE_TYPE (arg))))
5361 : 0 : continue;
5362 : 186 : if (tree_zero_one_valued_p (arg))
5363 : 51 : kind[i] |= 2;
5364 : 186 : if (TREE_CODE (arg) == SSA_NAME)
5365 : : {
5366 : 184 : gimple *g = SSA_NAME_DEF_STMT (arg);
5367 : 184 : if (gimple_assign_cast_p (g))
5368 : : {
5369 : 30 : tree op = gimple_assign_rhs1 (g);
5370 : 30 : if (TREE_CODE (op) == SSA_NAME
5371 : 30 : && INTEGRAL_TYPE_P (TREE_TYPE (op)))
5372 : 30 : g = SSA_NAME_DEF_STMT (op);
5373 : : }
5374 : 184 : g = uaddc_ne0 (g);
5375 : 184 : if (!uaddc_is_cplxpart (g, IMAGPART_EXPR))
5376 : 124 : continue;
5377 : 60 : arg_im[i] = gimple_assign_lhs (g);
5378 : 60 : g = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (g), 0));
5379 : 60 : if (!is_gimple_call (g) || !gimple_call_internal_p (g))
5380 : 0 : continue;
5381 : 60 : switch (gimple_call_internal_fn (g))
5382 : : {
5383 : 60 : case IFN_ADD_OVERFLOW:
5384 : 60 : case IFN_SUB_OVERFLOW:
5385 : 60 : case IFN_UADDC:
5386 : 60 : case IFN_USUBC:
5387 : 60 : break;
5388 : 0 : default:
5389 : 0 : continue;
5390 : : }
5391 : 60 : kind[i] |= 4;
5392 : : }
5393 : : }
5394 : : /* Make arg2 the one with compatible type and arg3 the one
5395 : : with [0, 1] range. If both is true for both operands,
5396 : : prefer as arg3 result of __imag__ of some ifn. */
5397 : 93 : if ((kind[0] & 1) == 0 || ((kind[1] & 1) != 0 && kind[0] > kind[1]))
5398 : : {
5399 : 1 : std::swap (arg2, arg3);
5400 : 1 : std::swap (kind[0], kind[1]);
5401 : 1 : std::swap (arg_im[0], arg_im[1]);
5402 : : }
5403 : 93 : if ((kind[0] & 1) == 0 || (kind[1] & 6) == 0)
5404 : : return false;
5405 : 69 : if (!has_single_use (gimple_assign_lhs (im1))
5406 : 67 : || !has_single_use (gimple_assign_lhs (im2))
5407 : 67 : || !has_single_use (gimple_assign_lhs (re1))
5408 : 136 : || num_imm_uses (gimple_call_lhs (ovf1)) != 2)
5409 : : return false;
5410 : : /* Check that ovf2's result is used in __real__ and set re2
5411 : : to that statement. */
5412 : 67 : use_operand_p use_p;
5413 : 67 : imm_use_iterator iter;
5414 : 67 : tree lhs = gimple_call_lhs (ovf2);
5415 : 200 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
5416 : : {
5417 : 133 : gimple *use_stmt = USE_STMT (use_p);
5418 : 133 : if (is_gimple_debug (use_stmt))
5419 : 0 : continue;
5420 : 133 : if (use_stmt == im2)
5421 : 67 : continue;
5422 : 66 : if (re2)
5423 : : return false;
5424 : 66 : if (!uaddc_is_cplxpart (use_stmt, REALPART_EXPR))
5425 : : return false;
5426 : : re2 = use_stmt;
5427 : : }
5428 : : /* Build .UADDC/.USUBC call which will be placed before the stmt. */
5429 : 67 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf2);
5430 : 67 : gimple *g;
5431 : 67 : if ((kind[1] & 4) != 0 && types_compatible_p (type, TREE_TYPE (arg_im[1])))
5432 : : arg3 = arg_im[1];
5433 : 67 : if ((kind[1] & 1) == 0)
5434 : : {
5435 : 25 : if (TREE_CODE (arg3) == INTEGER_CST)
5436 : 0 : arg3 = fold_convert (type, arg3);
5437 : : else
5438 : : {
5439 : 25 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, arg3);
5440 : 25 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5441 : 25 : arg3 = gimple_assign_lhs (g);
5442 : : }
5443 : : }
5444 : 89 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5445 : : ? IFN_UADDC : IFN_USUBC,
5446 : : 3, arg1, arg2, arg3);
5447 : 67 : tree nlhs = make_ssa_name (TREE_TYPE (lhs));
5448 : 67 : gimple_call_set_lhs (g, nlhs);
5449 : 67 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5450 : : /* In the case where stmt is | or ^ of two overflow flags
5451 : : or addition of those, replace stmt with __imag__ of the above
5452 : : added call. In case of arg1 + arg2 + (ovf1 + ovf2) or
5453 : : arg1 - arg2 - (ovf1 + ovf2) just emit it before stmt. */
5454 : 67 : tree ilhs = rhs[2] ? make_ssa_name (type) : gimple_assign_lhs (stmt);
5455 : 67 : g = gimple_build_assign (ilhs, IMAGPART_EXPR,
5456 : 67 : build1 (IMAGPART_EXPR, TREE_TYPE (ilhs), nlhs));
5457 : 67 : if (rhs[2])
5458 : : {
5459 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5460 : : /* Remove some further statements which can't be kept in the IL because
5461 : : they can use SSA_NAMEs whose setter is going to be removed too. */
5462 : 75 : for (gimple *g2 : temp_stmts)
5463 : : {
5464 : 30 : gsi2 = gsi_for_stmt (g2);
5465 : 30 : gsi_remove (&gsi2, true);
5466 : 30 : release_defs (g2);
5467 : : }
5468 : : }
5469 : : else
5470 : 52 : gsi_replace (gsi, g, true);
5471 : : /* Remove some statements which can't be kept in the IL because they
5472 : : use SSA_NAME whose setter is going to be removed too. */
5473 : 67 : tree rhs1 = rhs[1];
5474 : 103 : for (int i = 0; i < 2; i++)
5475 : 85 : if (rhs1 == gimple_assign_lhs (im2))
5476 : : break;
5477 : : else
5478 : : {
5479 : 36 : g = SSA_NAME_DEF_STMT (rhs1);
5480 : 36 : rhs1 = gimple_assign_rhs1 (g);
5481 : 36 : gsi2 = gsi_for_stmt (g);
5482 : 36 : gsi_remove (&gsi2, true);
5483 : 36 : release_defs (g);
5484 : : }
5485 : 67 : gcc_checking_assert (rhs1 == gimple_assign_lhs (im2));
5486 : 67 : gsi2 = gsi_for_stmt (im2);
5487 : 67 : gsi_remove (&gsi2, true);
5488 : 67 : release_defs (im2);
5489 : : /* Replace the re2 statement with __real__ of the newly added
5490 : : .UADDC/.USUBC call. */
5491 : 67 : if (re2)
5492 : : {
5493 : 66 : gsi2 = gsi_for_stmt (re2);
5494 : 66 : tree rlhs = gimple_assign_lhs (re2);
5495 : 66 : g = gimple_build_assign (rlhs, REALPART_EXPR,
5496 : 66 : build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
5497 : 66 : gsi_replace (&gsi2, g, true);
5498 : : }
5499 : 67 : if (rhs[2])
5500 : : {
5501 : : /* If this is the arg1 + arg2 + (ovf1 + ovf2) or
5502 : : arg1 - arg2 - (ovf1 + ovf2) case for the most significant limb,
5503 : : replace stmt with __real__ of another .UADDC/.USUBC call which
5504 : : handles the most significant limb. Overflow flag from this is
5505 : : ignored. */
5506 : 17 : g = gimple_build_call_internal (code == PLUS_EXPR
5507 : : ? IFN_UADDC : IFN_USUBC,
5508 : : 3, rhs[3], rhs[2], ilhs);
5509 : 15 : nlhs = make_ssa_name (TREE_TYPE (lhs));
5510 : 15 : gimple_call_set_lhs (g, nlhs);
5511 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5512 : 15 : ilhs = gimple_assign_lhs (stmt);
5513 : 15 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5514 : 15 : build1 (REALPART_EXPR, TREE_TYPE (ilhs), nlhs));
5515 : 15 : gsi_replace (gsi, g, true);
5516 : : }
5517 : 67 : if (TREE_CODE (arg3) == SSA_NAME)
5518 : : {
5519 : : /* When pattern recognizing the second least significant limb
5520 : : above (i.e. first pair of .{ADD,SUB}_OVERFLOW calls for one limb),
5521 : : check if the [0, 1] range argument (i.e. carry in) isn't the
5522 : : result of another .{ADD,SUB}_OVERFLOW call (one handling the
5523 : : least significant limb). Again look through casts and != 0. */
5524 : 67 : gimple *im3 = SSA_NAME_DEF_STMT (arg3);
5525 : 92 : for (int i = 0; i < 2; ++i)
5526 : : {
5527 : 92 : gimple *im4 = uaddc_cast (im3);
5528 : 92 : if (im4 == im3)
5529 : : break;
5530 : : else
5531 : 25 : im3 = im4;
5532 : : }
5533 : 67 : im3 = uaddc_ne0 (im3);
5534 : 67 : if (uaddc_is_cplxpart (im3, IMAGPART_EXPR))
5535 : : {
5536 : 60 : gimple *ovf3
5537 : 60 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
5538 : 60 : if (gimple_call_internal_p (ovf3, ifn))
5539 : : {
5540 : 25 : lhs = gimple_call_lhs (ovf3);
5541 : 25 : arg1 = gimple_call_arg (ovf3, 0);
5542 : 25 : arg2 = gimple_call_arg (ovf3, 1);
5543 : 25 : if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
5544 : 25 : && types_compatible_p (type, TREE_TYPE (arg1))
5545 : 50 : && types_compatible_p (type, TREE_TYPE (arg2)))
5546 : : {
5547 : : /* And if it is initialized from result of __imag__
5548 : : of .{ADD,SUB}_OVERFLOW call, replace that
5549 : : call with .U{ADD,SUB}C call with the same arguments,
5550 : : just 0 added as third argument. This isn't strictly
5551 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5552 : : produce the same result, but may result in better
5553 : : generated code on some targets where the backend can
5554 : : better prepare in how the result will be used. */
5555 : 25 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5556 : : ? IFN_UADDC : IFN_USUBC,
5557 : : 3, arg1, arg2,
5558 : : build_zero_cst (type));
5559 : 25 : gimple_call_set_lhs (g, lhs);
5560 : 25 : gsi2 = gsi_for_stmt (ovf3);
5561 : 25 : gsi_replace (&gsi2, g, true);
5562 : : }
5563 : : }
5564 : : }
5565 : : }
5566 : : return true;
5567 : 1606676 : }
5568 : :
5569 : : /* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
5570 : : (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
5571 : : isn't a direct optab. Also handle `<=`/`>` to be
5572 : : `x & (x - 1) !=/== x`. */
5573 : :
5574 : : static void
5575 : 4422052 : match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
5576 : : {
5577 : 4422052 : tree clhs, crhs;
5578 : 4422052 : enum tree_code code;
5579 : 4422052 : bool was_le = false;
5580 : 4422052 : if (gimple_code (stmt) == GIMPLE_COND)
5581 : : {
5582 : 4117502 : clhs = gimple_cond_lhs (stmt);
5583 : 4117502 : crhs = gimple_cond_rhs (stmt);
5584 : 4117502 : code = gimple_cond_code (stmt);
5585 : : }
5586 : : else
5587 : : {
5588 : 304550 : clhs = gimple_assign_rhs1 (stmt);
5589 : 304550 : crhs = gimple_assign_rhs2 (stmt);
5590 : 304550 : code = gimple_assign_rhs_code (stmt);
5591 : : }
5592 : 4422052 : if (code != LE_EXPR && code != GT_EXPR
5593 : 4422052 : && code != EQ_EXPR && code != NE_EXPR)
5594 : 4422046 : return;
5595 : 2035333 : if (code == LE_EXPR || code == GT_EXPR)
5596 : 4164768 : was_le = true;
5597 : 4164768 : if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
5598 : 4008534 : return;
5599 : 156234 : gimple *call = SSA_NAME_DEF_STMT (clhs);
5600 : 156234 : combined_fn cfn = gimple_call_combined_fn (call);
5601 : 156234 : switch (cfn)
5602 : : {
5603 : 15 : CASE_CFN_POPCOUNT:
5604 : 15 : break;
5605 : : default:
5606 : : return;
5607 : : }
5608 : 15 : if (!has_single_use (clhs))
5609 : : return;
5610 : 14 : tree arg = gimple_call_arg (call, 0);
5611 : 14 : tree type = TREE_TYPE (arg);
5612 : 14 : if (!INTEGRAL_TYPE_P (type))
5613 : : return;
5614 : 14 : bool nonzero_arg = tree_expr_nonzero_p (arg);
5615 : 14 : if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
5616 : : {
5617 : : /* Tell expand_POPCOUNT the popcount result is only used in equality
5618 : : comparison with one, so that it can decide based on rtx costs. */
5619 : 16 : gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
5620 : : was_le ? integer_minus_one_node
5621 : 8 : : (nonzero_arg ? integer_zero_node
5622 : : : integer_one_node));
5623 : 8 : gimple_call_set_lhs (g, gimple_call_lhs (call));
5624 : 8 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5625 : 8 : gsi_replace (&gsi2, g, true);
5626 : 8 : return;
5627 : : }
5628 : 6 : tree argm1 = make_ssa_name (type);
5629 : 6 : gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
5630 : : build_int_cst (type, -1));
5631 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5632 : 6 : g = gimple_build_assign (make_ssa_name (type),
5633 : 6 : (nonzero_arg || was_le) ? BIT_AND_EXPR : BIT_XOR_EXPR,
5634 : : arg, argm1);
5635 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5636 : 6 : tree_code cmpcode;
5637 : 6 : if (was_le)
5638 : : {
5639 : 0 : argm1 = build_zero_cst (type);
5640 : 0 : cmpcode = code == LE_EXPR ? EQ_EXPR : NE_EXPR;
5641 : : }
5642 : 6 : else if (nonzero_arg)
5643 : : {
5644 : 2 : argm1 = build_zero_cst (type);
5645 : 2 : cmpcode = code;
5646 : : }
5647 : : else
5648 : 4 : cmpcode = code == EQ_EXPR ? GT_EXPR : LE_EXPR;
5649 : 6 : if (gcond *cond = dyn_cast <gcond *> (stmt))
5650 : : {
5651 : 2 : gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
5652 : 2 : gimple_cond_set_rhs (cond, argm1);
5653 : 2 : gimple_cond_set_code (cond, cmpcode);
5654 : : }
5655 : : else
5656 : : {
5657 : 4 : gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
5658 : 4 : gimple_assign_set_rhs2 (stmt, argm1);
5659 : 4 : gimple_assign_set_rhs_code (stmt, cmpcode);
5660 : : }
5661 : 6 : update_stmt (stmt);
5662 : 6 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5663 : 6 : gsi_remove (&gsi2, true);
5664 : 6 : release_defs (call);
5665 : : }
5666 : :
5667 : : /* Return true if target has support for divmod. */
5668 : :
5669 : : static bool
5670 : 27659 : target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
5671 : : {
5672 : : /* If target supports hardware divmod insn, use it for divmod. */
5673 : 27659 : if (optab_handler (divmod_optab, mode) != CODE_FOR_nothing)
5674 : : return true;
5675 : :
5676 : : /* Check if libfunc for divmod is available. */
5677 : 2664 : rtx libfunc = optab_libfunc (divmod_optab, mode);
5678 : 2664 : if (libfunc != NULL_RTX)
5679 : : {
5680 : : /* If optab_handler exists for div_optab, perhaps in a wider mode,
5681 : : we don't want to use the libfunc even if it exists for given mode. */
5682 : : machine_mode div_mode;
5683 : 11088 : FOR_EACH_MODE_FROM (div_mode, mode)
5684 : 8424 : if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
5685 : : return false;
5686 : :
5687 : 2664 : return targetm.expand_divmod_libfunc != NULL;
5688 : : }
5689 : :
5690 : : return false;
5691 : : }
5692 : :
5693 : : /* Check if stmt is candidate for divmod transform. */
5694 : :
5695 : : static bool
5696 : 54070 : divmod_candidate_p (gassign *stmt)
5697 : : {
5698 : 54070 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
5699 : 54070 : machine_mode mode = TYPE_MODE (type);
5700 : 54070 : optab divmod_optab, div_optab;
5701 : :
5702 : 54070 : if (TYPE_UNSIGNED (type))
5703 : : {
5704 : : divmod_optab = udivmod_optab;
5705 : : div_optab = udiv_optab;
5706 : : }
5707 : : else
5708 : : {
5709 : 21958 : divmod_optab = sdivmod_optab;
5710 : 21958 : div_optab = sdiv_optab;
5711 : : }
5712 : :
5713 : 54070 : tree op1 = gimple_assign_rhs1 (stmt);
5714 : 54070 : tree op2 = gimple_assign_rhs2 (stmt);
5715 : :
5716 : : /* Disable the transform if either is a constant, since division-by-constant
5717 : : may have specialized expansion. */
5718 : 54070 : if (CONSTANT_CLASS_P (op1))
5719 : : return false;
5720 : :
5721 : 50420 : if (CONSTANT_CLASS_P (op2))
5722 : : {
5723 : 25080 : if (integer_pow2p (op2))
5724 : : return false;
5725 : :
5726 : 22691 : if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
5727 : 23773 : && element_precision (type) <= BITS_PER_WORD)
5728 : : return false;
5729 : :
5730 : : /* If the divisor is not power of 2 and the precision wider than
5731 : : HWI, expand_divmod punts on that, so in that case it is better
5732 : : to use divmod optab or libfunc. Similarly if choose_multiplier
5733 : : might need pre/post shifts of BITS_PER_WORD or more. */
5734 : : }
5735 : :
5736 : : /* Exclude the case where TYPE_OVERFLOW_TRAPS (type) as that should
5737 : : expand using the [su]divv optabs. */
5738 : 27659 : if (TYPE_OVERFLOW_TRAPS (type))
5739 : : return false;
5740 : :
5741 : 27659 : if (!target_supports_divmod_p (divmod_optab, div_optab, mode))
5742 : : return false;
5743 : :
5744 : : return true;
5745 : : }
5746 : :
5747 : : /* This function looks for:
5748 : : t1 = a TRUNC_DIV_EXPR b;
5749 : : t2 = a TRUNC_MOD_EXPR b;
5750 : : and transforms it to the following sequence:
5751 : : complex_tmp = DIVMOD (a, b);
5752 : : t1 = REALPART_EXPR(a);
5753 : : t2 = IMAGPART_EXPR(b);
5754 : : For conditions enabling the transform see divmod_candidate_p().
5755 : :
5756 : : The pass has three parts:
5757 : : 1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
5758 : : other trunc_div_expr and trunc_mod_expr stmts.
5759 : : 2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
5760 : : to stmts vector.
5761 : : 3) Insert DIVMOD call just before top_stmt and update entries in
5762 : : stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
5763 : : IMAGPART_EXPR for mod). */
5764 : :
5765 : : static bool
5766 : 54093 : convert_to_divmod (gassign *stmt)
5767 : : {
5768 : 54093 : if (stmt_can_throw_internal (cfun, stmt)
5769 : 54093 : || !divmod_candidate_p (stmt))
5770 : 26434 : return false;
5771 : :
5772 : 27659 : tree op1 = gimple_assign_rhs1 (stmt);
5773 : 27659 : tree op2 = gimple_assign_rhs2 (stmt);
5774 : :
5775 : 27659 : imm_use_iterator use_iter;
5776 : 27659 : gimple *use_stmt;
5777 : 27659 : auto_vec<gimple *> stmts;
5778 : :
5779 : 27659 : gimple *top_stmt = stmt;
5780 : 27659 : basic_block top_bb = gimple_bb (stmt);
5781 : :
5782 : : /* Part 1: Try to set top_stmt to "topmost" stmt that dominates
5783 : : at-least stmt and possibly other trunc_div/trunc_mod stmts
5784 : : having same operands as stmt. */
5785 : :
5786 : 116970 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op1)
5787 : : {
5788 : 89311 : if (is_gimple_assign (use_stmt)
5789 : 54648 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5790 : 43097 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5791 : 45590 : && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0)
5792 : 134784 : && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0))
5793 : : {
5794 : 39132 : if (stmt_can_throw_internal (cfun, use_stmt))
5795 : 0 : continue;
5796 : :
5797 : 39132 : basic_block bb = gimple_bb (use_stmt);
5798 : :
5799 : 39132 : if (bb == top_bb)
5800 : : {
5801 : 38411 : if (gimple_uid (use_stmt) < gimple_uid (top_stmt))
5802 : 5180 : top_stmt = use_stmt;
5803 : : }
5804 : 721 : else if (dominated_by_p (CDI_DOMINATORS, top_bb, bb))
5805 : : {
5806 : 182 : top_bb = bb;
5807 : 182 : top_stmt = use_stmt;
5808 : : }
5809 : : }
5810 : 27659 : }
5811 : :
5812 : 27659 : tree top_op1 = gimple_assign_rhs1 (top_stmt);
5813 : 27659 : tree top_op2 = gimple_assign_rhs2 (top_stmt);
5814 : :
5815 : 27659 : stmts.safe_push (top_stmt);
5816 : 27659 : bool div_seen = (gimple_assign_rhs_code (top_stmt) == TRUNC_DIV_EXPR);
5817 : :
5818 : : /* Part 2: Add all trunc_div/trunc_mod statements domianted by top_bb
5819 : : to stmts vector. The 2nd loop will always add stmt to stmts vector, since
5820 : : gimple_bb (top_stmt) dominates gimple_bb (stmt), so the
5821 : : 2nd loop ends up adding at-least single trunc_mod_expr stmt. */
5822 : :
5823 : 116970 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, top_op1)
5824 : : {
5825 : 89311 : if (is_gimple_assign (use_stmt)
5826 : 54648 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5827 : 43097 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5828 : 45590 : && operand_equal_p (top_op1, gimple_assign_rhs1 (use_stmt), 0)
5829 : 134784 : && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0))
5830 : : {
5831 : 66889 : if (use_stmt == top_stmt
5832 : 11473 : || stmt_can_throw_internal (cfun, use_stmt)
5833 : 50605 : || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb))
5834 : 27757 : continue;
5835 : :
5836 : 11375 : stmts.safe_push (use_stmt);
5837 : 11375 : if (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR)
5838 : 89311 : div_seen = true;
5839 : : }
5840 : 27659 : }
5841 : :
5842 : 27659 : if (!div_seen)
5843 : : return false;
5844 : :
5845 : : /* Part 3: Create libcall to internal fn DIVMOD:
5846 : : divmod_tmp = DIVMOD (op1, op2). */
5847 : :
5848 : 11347 : gcall *call_stmt = gimple_build_call_internal (IFN_DIVMOD, 2, op1, op2);
5849 : 11347 : tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
5850 : : call_stmt, "divmod_tmp");
5851 : 11347 : gimple_call_set_lhs (call_stmt, res);
5852 : : /* We rejected throwing statements above. */
5853 : 11347 : gimple_call_set_nothrow (call_stmt, true);
5854 : :
5855 : : /* Insert the call before top_stmt. */
5856 : 11347 : gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
5857 : 11347 : gsi_insert_before (&top_stmt_gsi, call_stmt, GSI_SAME_STMT);
5858 : :
5859 : 11347 : widen_mul_stats.divmod_calls_inserted++;
5860 : :
5861 : : /* Update all statements in stmts vector:
5862 : : lhs = op1 TRUNC_DIV_EXPR op2 -> lhs = REALPART_EXPR<divmod_tmp>
5863 : : lhs = op1 TRUNC_MOD_EXPR op2 -> lhs = IMAGPART_EXPR<divmod_tmp>. */
5864 : :
5865 : 61726 : for (unsigned i = 0; stmts.iterate (i, &use_stmt); ++i)
5866 : : {
5867 : 22720 : tree new_rhs;
5868 : :
5869 : 22720 : switch (gimple_assign_rhs_code (use_stmt))
5870 : : {
5871 : 11357 : case TRUNC_DIV_EXPR:
5872 : 11357 : new_rhs = fold_build1 (REALPART_EXPR, TREE_TYPE (op1), res);
5873 : 11357 : break;
5874 : :
5875 : 11363 : case TRUNC_MOD_EXPR:
5876 : 11363 : new_rhs = fold_build1 (IMAGPART_EXPR, TREE_TYPE (op1), res);
5877 : 11363 : break;
5878 : :
5879 : 0 : default:
5880 : 0 : gcc_unreachable ();
5881 : : }
5882 : :
5883 : 22720 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
5884 : 22720 : gimple_assign_set_rhs_from_tree (&gsi, new_rhs);
5885 : 22720 : update_stmt (use_stmt);
5886 : : }
5887 : :
5888 : : return true;
5889 : 27659 : }
5890 : :
5891 : : /* Process a single gimple assignment STMT, which has a RSHIFT_EXPR as
5892 : : its rhs, and try to convert it into a MULT_HIGHPART_EXPR. The return
5893 : : value is true iff we converted the statement. */
5894 : :
5895 : : static bool
5896 : 169495 : convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
5897 : : {
5898 : 169495 : tree lhs = gimple_assign_lhs (stmt);
5899 : 169495 : tree stype = TREE_TYPE (lhs);
5900 : 169495 : tree sarg0 = gimple_assign_rhs1 (stmt);
5901 : 169495 : tree sarg1 = gimple_assign_rhs2 (stmt);
5902 : :
5903 : 169495 : if (TREE_CODE (stype) != INTEGER_TYPE
5904 : 163303 : || TREE_CODE (sarg1) != INTEGER_CST
5905 : 147438 : || TREE_CODE (sarg0) != SSA_NAME
5906 : 147437 : || !tree_fits_uhwi_p (sarg1)
5907 : 316932 : || !has_single_use (sarg0))
5908 : : return false;
5909 : :
5910 : 41687 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (sarg0));
5911 : 38825 : if (!def)
5912 : : return false;
5913 : :
5914 : 38825 : enum tree_code mcode = gimple_assign_rhs_code (def);
5915 : 38825 : if (mcode == NOP_EXPR)
5916 : : {
5917 : 5605 : tree tmp = gimple_assign_rhs1 (def);
5918 : 5605 : if (TREE_CODE (tmp) != SSA_NAME || !has_single_use (tmp))
5919 : : return false;
5920 : 170224 : def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (tmp));
5921 : 1569 : if (!def)
5922 : : return false;
5923 : 1569 : mcode = gimple_assign_rhs_code (def);
5924 : : }
5925 : :
5926 : 34789 : if (mcode != WIDEN_MULT_EXPR
5927 : 34789 : || gimple_bb (def) != gimple_bb (stmt))
5928 : : return false;
5929 : 841 : tree mtype = TREE_TYPE (gimple_assign_lhs (def));
5930 : 841 : if (TREE_CODE (mtype) != INTEGER_TYPE
5931 : 841 : || TYPE_PRECISION (mtype) != TYPE_PRECISION (stype))
5932 : : return false;
5933 : :
5934 : 841 : tree mop1 = gimple_assign_rhs1 (def);
5935 : 841 : tree mop2 = gimple_assign_rhs2 (def);
5936 : 841 : tree optype = TREE_TYPE (mop1);
5937 : 841 : bool unsignedp = TYPE_UNSIGNED (optype);
5938 : 841 : unsigned int prec = TYPE_PRECISION (optype);
5939 : :
5940 : 841 : if (unsignedp != TYPE_UNSIGNED (mtype)
5941 : 841 : || TYPE_PRECISION (mtype) != 2 * prec)
5942 : : return false;
5943 : :
5944 : 841 : unsigned HOST_WIDE_INT bits = tree_to_uhwi (sarg1);
5945 : 841 : if (bits < prec || bits >= 2 * prec)
5946 : : return false;
5947 : :
5948 : : /* For the time being, require operands to have the same sign. */
5949 : 840 : if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2)))
5950 : : return false;
5951 : :
5952 : 840 : machine_mode mode = TYPE_MODE (optype);
5953 : 840 : optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
5954 : 840 : if (optab_handler (tab, mode) == CODE_FOR_nothing)
5955 : : return false;
5956 : :
5957 : 840 : location_t loc = gimple_location (stmt);
5958 : 840 : tree highpart1 = build_and_insert_binop (gsi, loc, "highparttmp",
5959 : : MULT_HIGHPART_EXPR, mop1, mop2);
5960 : 840 : tree highpart2 = highpart1;
5961 : 840 : tree ntype = optype;
5962 : :
5963 : 840 : if (TYPE_UNSIGNED (stype) != TYPE_UNSIGNED (optype))
5964 : : {
5965 : 16 : ntype = TYPE_UNSIGNED (stype) ? unsigned_type_for (optype)
5966 : 7 : : signed_type_for (optype);
5967 : 16 : highpart2 = build_and_insert_cast (gsi, loc, ntype, highpart1);
5968 : : }
5969 : 840 : if (bits > prec)
5970 : 29 : highpart2 = build_and_insert_binop (gsi, loc, "highparttmp",
5971 : : RSHIFT_EXPR, highpart2,
5972 : 29 : build_int_cst (ntype, bits - prec));
5973 : :
5974 : 840 : gassign *new_stmt = gimple_build_assign (lhs, NOP_EXPR, highpart2);
5975 : 840 : gsi_replace (gsi, new_stmt, true);
5976 : :
5977 : 840 : widen_mul_stats.highpart_mults_inserted++;
5978 : 840 : return true;
5979 : : }
5980 : :
5981 : : /* If target has spaceship<MODE>3 expander, pattern recognize
5982 : : <bb 2> [local count: 1073741824]:
5983 : : if (a_2(D) == b_3(D))
5984 : : goto <bb 6>; [34.00%]
5985 : : else
5986 : : goto <bb 3>; [66.00%]
5987 : :
5988 : : <bb 3> [local count: 708669601]:
5989 : : if (a_2(D) < b_3(D))
5990 : : goto <bb 6>; [1.04%]
5991 : : else
5992 : : goto <bb 4>; [98.96%]
5993 : :
5994 : : <bb 4> [local count: 701299439]:
5995 : : if (a_2(D) > b_3(D))
5996 : : goto <bb 5>; [48.89%]
5997 : : else
5998 : : goto <bb 6>; [51.11%]
5999 : :
6000 : : <bb 5> [local count: 342865295]:
6001 : :
6002 : : <bb 6> [local count: 1073741824]:
6003 : : and turn it into:
6004 : : <bb 2> [local count: 1073741824]:
6005 : : _1 = .SPACESHIP (a_2(D), b_3(D), 0);
6006 : : if (_1 == 0)
6007 : : goto <bb 6>; [34.00%]
6008 : : else
6009 : : goto <bb 3>; [66.00%]
6010 : :
6011 : : <bb 3> [local count: 708669601]:
6012 : : if (_1 == -1)
6013 : : goto <bb 6>; [1.04%]
6014 : : else
6015 : : goto <bb 4>; [98.96%]
6016 : :
6017 : : <bb 4> [local count: 701299439]:
6018 : : if (_1 == 1)
6019 : : goto <bb 5>; [48.89%]
6020 : : else
6021 : : goto <bb 6>; [51.11%]
6022 : :
6023 : : <bb 5> [local count: 342865295]:
6024 : :
6025 : : <bb 6> [local count: 1073741824]:
6026 : : so that the backend can emit optimal comparison and
6027 : : conditional jump sequence. If the
6028 : : <bb 6> [local count: 1073741824]:
6029 : : above has a single PHI like:
6030 : : # _27 = PHI<0(2), -1(3), 2(4), 1(5)>
6031 : : then replace it with effectively
6032 : : _1 = .SPACESHIP (a_2(D), b_3(D), 1);
6033 : : _27 = _1; */
6034 : :
6035 : : static void
6036 : 4117502 : optimize_spaceship (gcond *stmt)
6037 : : {
6038 : 4117502 : enum tree_code code = gimple_cond_code (stmt);
6039 : 4117502 : if (code != EQ_EXPR && code != NE_EXPR)
6040 : 4117166 : return;
6041 : 3339801 : tree arg1 = gimple_cond_lhs (stmt);
6042 : 3339801 : tree arg2 = gimple_cond_rhs (stmt);
6043 : 3339801 : if ((!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1))
6044 : 3231065 : && !INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
6045 : 2619923 : || optab_handler (spaceship_optab,
6046 : 2619923 : TYPE_MODE (TREE_TYPE (arg1))) == CODE_FOR_nothing
6047 : 5919486 : || operand_equal_p (arg1, arg2, 0))
6048 : 761178 : return;
6049 : :
6050 : 2578623 : basic_block bb0 = gimple_bb (stmt), bb1, bb2 = NULL;
6051 : 2578623 : edge em1 = NULL, e1 = NULL, e2 = NULL;
6052 : 2578623 : bb1 = EDGE_SUCC (bb0, 1)->dest;
6053 : 2578623 : if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
6054 : 1550878 : bb1 = EDGE_SUCC (bb0, 0)->dest;
6055 : :
6056 : 7582405 : gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
6057 : 1093868 : if (g == NULL
6058 : 1093868 : || !single_pred_p (bb1)
6059 : 707917 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6060 : 591042 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6061 : 474167 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6062 : 1715 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6063 : 602177 : || !cond_only_block_p (bb1))
6064 : 2568302 : return;
6065 : :
6066 : 10321 : enum tree_code ccode = (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6067 : 10321 : ? LT_EXPR : GT_EXPR);
6068 : 10321 : switch (gimple_cond_code (g))
6069 : : {
6070 : : case LT_EXPR:
6071 : : case LE_EXPR:
6072 : : break;
6073 : 7843 : case GT_EXPR:
6074 : 7843 : case GE_EXPR:
6075 : 7843 : ccode = ccode == LT_EXPR ? GT_EXPR : LT_EXPR;
6076 : : break;
6077 : : default:
6078 : : return;
6079 : : }
6080 : :
6081 : 30720 : for (int i = 0; i < 2; ++i)
6082 : : {
6083 : : /* With NaNs, </<=/>/>= are false, so we need to look for the
6084 : : third comparison on the false edge from whatever non-equality
6085 : : comparison the second comparison is. */
6086 : 20634 : if (HONOR_NANS (TREE_TYPE (arg1))
6087 : 20634 : && (EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0)
6088 : 343 : continue;
6089 : :
6090 : 20291 : bb2 = EDGE_SUCC (bb1, i)->dest;
6091 : 60152 : g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
6092 : 13123 : if (g == NULL
6093 : 13123 : || !single_pred_p (bb2)
6094 : 18093 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6095 : 10146 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6096 : 2199 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6097 : 12 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6098 : 234 : || !cond_only_block_p (bb2)
6099 : 10380 : || EDGE_SUCC (bb2, 0)->dest == EDGE_SUCC (bb2, 1)->dest)
6100 : 20057 : continue;
6101 : :
6102 : 234 : enum tree_code ccode2
6103 : 234 : = (operand_equal_p (gimple_cond_lhs (g), arg1, 0) ? LT_EXPR : GT_EXPR);
6104 : 234 : switch (gimple_cond_code (g))
6105 : : {
6106 : : case LT_EXPR:
6107 : : case LE_EXPR:
6108 : : break;
6109 : 143 : case GT_EXPR:
6110 : 143 : case GE_EXPR:
6111 : 143 : ccode2 = ccode2 == LT_EXPR ? GT_EXPR : LT_EXPR;
6112 : : break;
6113 : 0 : default:
6114 : 0 : continue;
6115 : : }
6116 : 234 : if (HONOR_NANS (TREE_TYPE (arg1)) && ccode == ccode2)
6117 : 0 : continue;
6118 : :
6119 : 468 : if ((ccode == LT_EXPR)
6120 : 234 : ^ ((EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0))
6121 : : {
6122 : 143 : em1 = EDGE_SUCC (bb1, 1 - i);
6123 : 143 : e1 = EDGE_SUCC (bb2, 0);
6124 : 143 : e2 = EDGE_SUCC (bb2, 1);
6125 : 143 : if ((ccode2 == LT_EXPR) ^ ((e1->flags & EDGE_TRUE_VALUE) == 0))
6126 : 0 : std::swap (e1, e2);
6127 : : }
6128 : : else
6129 : : {
6130 : 91 : e1 = EDGE_SUCC (bb1, 1 - i);
6131 : 91 : em1 = EDGE_SUCC (bb2, 0);
6132 : 91 : e2 = EDGE_SUCC (bb2, 1);
6133 : 91 : if ((ccode2 != LT_EXPR) ^ ((em1->flags & EDGE_TRUE_VALUE) == 0))
6134 : : std::swap (em1, e2);
6135 : : }
6136 : : break;
6137 : : }
6138 : :
6139 : 10229 : if (em1 == NULL)
6140 : : {
6141 : 20172 : if ((ccode == LT_EXPR)
6142 : 10086 : ^ ((EDGE_SUCC (bb1, 0)->flags & EDGE_TRUE_VALUE) != 0))
6143 : : {
6144 : 3000 : em1 = EDGE_SUCC (bb1, 1);
6145 : 3000 : e1 = EDGE_SUCC (bb1, 0);
6146 : 3000 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6147 : : }
6148 : : else
6149 : : {
6150 : 7086 : em1 = EDGE_SUCC (bb1, 0);
6151 : 7086 : e1 = EDGE_SUCC (bb1, 1);
6152 : 7086 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6153 : : }
6154 : : }
6155 : :
6156 : : /* Check if there is a single bb into which all failed conditions
6157 : : jump to (perhaps through an empty block) and if it results in
6158 : : a single integral PHI which just sets it to -1, 0, 1, X
6159 : : (or -1, 0, 1 when NaNs can't happen). In that case use 1 rather
6160 : : than 0 as last .SPACESHIP argument to tell backends it might
6161 : : consider different code generation and just cast the result
6162 : : of .SPACESHIP to the PHI result. X above is some value
6163 : : other than -1, 0, 1, for libstdc++ 2, for libc++ -127. */
6164 : 10320 : tree arg3 = integer_zero_node;
6165 : 10320 : edge e = EDGE_SUCC (bb0, 0);
6166 : 10320 : if (e->dest == bb1)
6167 : 6786 : e = EDGE_SUCC (bb0, 1);
6168 : 10320 : basic_block bbp = e->dest;
6169 : 10320 : gphi *phi = NULL;
6170 : 10320 : for (gphi_iterator psi = gsi_start_phis (bbp);
6171 : 12498 : !gsi_end_p (psi); gsi_next (&psi))
6172 : : {
6173 : 4026 : gphi *gp = psi.phi ();
6174 : 4026 : tree res = gimple_phi_result (gp);
6175 : :
6176 : 4026 : if (phi != NULL
6177 : 3592 : || virtual_operand_p (res)
6178 : 2442 : || !INTEGRAL_TYPE_P (TREE_TYPE (res))
6179 : 6328 : || TYPE_PRECISION (TREE_TYPE (res)) < 2)
6180 : : {
6181 : : phi = NULL;
6182 : : break;
6183 : : }
6184 : 2178 : phi = gp;
6185 : : }
6186 : 10320 : if (phi
6187 : 1744 : && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
6188 : 10798 : && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
6189 : : {
6190 : 95 : HOST_WIDE_INT argval = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? 2 : -1;
6191 : 566 : for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
6192 : : {
6193 : 206 : edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
6194 : 206 : if (e3->dest != bbp)
6195 : : {
6196 : 95 : if (!empty_block_p (e3->dest)
6197 : 85 : || !single_succ_p (e3->dest)
6198 : 180 : || single_succ (e3->dest) != bbp)
6199 : : {
6200 : : phi = NULL;
6201 : : break;
6202 : : }
6203 : : e3 = single_succ_edge (e3->dest);
6204 : : }
6205 : 196 : tree a = gimple_phi_arg_def_from_edge (phi, e3);
6206 : 196 : if (TREE_CODE (a) != INTEGER_CST
6207 : 196 : || (i == 0 && !integer_onep (a))
6208 : 388 : || (i == 1 && !integer_all_onesp (a)))
6209 : : {
6210 : : phi = NULL;
6211 : : break;
6212 : : }
6213 : 192 : if (i == 2)
6214 : : {
6215 : 30 : tree minv = TYPE_MIN_VALUE (signed_char_type_node);
6216 : 30 : tree maxv = TYPE_MAX_VALUE (signed_char_type_node);
6217 : 30 : widest_int w = widest_int::from (wi::to_wide (a), SIGNED);
6218 : 59 : if ((w >= -1 && w <= 1)
6219 : 26 : || w < wi::to_widest (minv)
6220 : 56 : || w > wi::to_widest (maxv))
6221 : : {
6222 : 4 : phi = NULL;
6223 : 4 : break;
6224 : : }
6225 : 26 : argval = w.to_shwi ();
6226 : 26 : }
6227 : : }
6228 : 95 : if (phi)
6229 : 77 : arg3 = build_int_cst (integer_type_node,
6230 : 89 : TYPE_UNSIGNED (TREE_TYPE (arg1)) ? 1 : argval);
6231 : : }
6232 : :
6233 : : /* For integral <=> comparisons only use .SPACESHIP if it is turned
6234 : : into an integer (-1, 0, 1). */
6235 : 10320 : if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) && arg3 == integer_zero_node)
6236 : : return;
6237 : :
6238 : 413 : gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 3, arg1, arg2, arg3);
6239 : 413 : tree lhs = make_ssa_name (integer_type_node);
6240 : 413 : gimple_call_set_lhs (gc, lhs);
6241 : 413 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6242 : 413 : gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
6243 : :
6244 : 749 : wide_int wmin = wi::minus_one (TYPE_PRECISION (integer_type_node));
6245 : 749 : wide_int wmax = wi::one (TYPE_PRECISION (integer_type_node));
6246 : 413 : if (HONOR_NANS (TREE_TYPE (arg1)))
6247 : : {
6248 : 343 : if (arg3 == integer_zero_node)
6249 : 317 : wmax = wi::two (TYPE_PRECISION (integer_type_node));
6250 : 26 : else if (tree_int_cst_sgn (arg3) < 0)
6251 : 1 : wmin = wi::to_wide (arg3);
6252 : : else
6253 : 25 : wmax = wi::to_wide (arg3);
6254 : : }
6255 : 749 : int_range<1> vr (TREE_TYPE (lhs), wmin, wmax);
6256 : 413 : set_range_info (lhs, vr);
6257 : :
6258 : 413 : if (arg3 != integer_zero_node)
6259 : : {
6260 : 77 : tree type = TREE_TYPE (gimple_phi_result (phi));
6261 : 77 : if (!useless_type_conversion_p (type, integer_type_node))
6262 : : {
6263 : 53 : tree tem = make_ssa_name (type);
6264 : 53 : gimple *gcv = gimple_build_assign (tem, NOP_EXPR, lhs);
6265 : 53 : gsi_insert_before (&gsi, gcv, GSI_SAME_STMT);
6266 : 53 : lhs = tem;
6267 : : }
6268 : 77 : SET_PHI_ARG_DEF_ON_EDGE (phi, e, lhs);
6269 : 77 : gimple_cond_set_lhs (stmt, boolean_false_node);
6270 : 77 : gimple_cond_set_rhs (stmt, boolean_false_node);
6271 : 141 : gimple_cond_set_code (stmt, (e->flags & EDGE_TRUE_VALUE)
6272 : : ? EQ_EXPR : NE_EXPR);
6273 : 77 : update_stmt (stmt);
6274 : 77 : return;
6275 : : }
6276 : :
6277 : 336 : gimple_cond_set_lhs (stmt, lhs);
6278 : 336 : gimple_cond_set_rhs (stmt, integer_zero_node);
6279 : 336 : update_stmt (stmt);
6280 : :
6281 : 672 : gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
6282 : 336 : gimple_cond_set_lhs (cond, lhs);
6283 : 336 : if (em1->src == bb1 && e2 != em1)
6284 : : {
6285 : 201 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6286 : 207 : gimple_cond_set_code (cond, (em1->flags & EDGE_TRUE_VALUE)
6287 : : ? EQ_EXPR : NE_EXPR);
6288 : : }
6289 : : else
6290 : : {
6291 : 135 : gcc_assert (e1->src == bb1 && e2 != e1);
6292 : 135 : gimple_cond_set_rhs (cond, integer_one_node);
6293 : 135 : gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
6294 : : ? EQ_EXPR : NE_EXPR);
6295 : : }
6296 : 336 : update_stmt (cond);
6297 : :
6298 : 336 : if (e2 != e1 && e2 != em1)
6299 : : {
6300 : 416 : cond = as_a <gcond *> (*gsi_last_bb (bb2));
6301 : 208 : gimple_cond_set_lhs (cond, lhs);
6302 : 208 : if (em1->src == bb2)
6303 : 91 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6304 : : else
6305 : : {
6306 : 117 : gcc_assert (e1->src == bb2);
6307 : 117 : gimple_cond_set_rhs (cond, integer_one_node);
6308 : : }
6309 : 208 : gimple_cond_set_code (cond,
6310 : 208 : (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
6311 : 208 : update_stmt (cond);
6312 : : }
6313 : : }
6314 : :
6315 : :
6316 : : /* Find integer multiplications where the operands are extended from
6317 : : smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
6318 : : or MULT_HIGHPART_EXPR where appropriate. */
6319 : :
6320 : : namespace {
6321 : :
6322 : : const pass_data pass_data_optimize_widening_mul =
6323 : : {
6324 : : GIMPLE_PASS, /* type */
6325 : : "widening_mul", /* name */
6326 : : OPTGROUP_NONE, /* optinfo_flags */
6327 : : TV_TREE_WIDEN_MUL, /* tv_id */
6328 : : PROP_ssa, /* properties_required */
6329 : : 0, /* properties_provided */
6330 : : 0, /* properties_destroyed */
6331 : : 0, /* todo_flags_start */
6332 : : TODO_update_ssa, /* todo_flags_finish */
6333 : : };
6334 : :
6335 : : class pass_optimize_widening_mul : public gimple_opt_pass
6336 : : {
6337 : : public:
6338 : 285081 : pass_optimize_widening_mul (gcc::context *ctxt)
6339 : 570162 : : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt)
6340 : : {}
6341 : :
6342 : : /* opt_pass methods: */
6343 : 1021582 : bool gate (function *) final override
6344 : : {
6345 : 1021582 : return flag_expensive_optimizations && optimize;
6346 : : }
6347 : :
6348 : : unsigned int execute (function *) final override;
6349 : :
6350 : : }; // class pass_optimize_widening_mul
6351 : :
6352 : : /* Walker class to perform the transformation in reverse dominance order. */
6353 : :
6354 : : class math_opts_dom_walker : public dom_walker
6355 : : {
6356 : : public:
6357 : : /* Constructor, CFG_CHANGED is a pointer to a boolean flag that will be set
6358 : : if walking modidifes the CFG. */
6359 : :
6360 : 948141 : math_opts_dom_walker (bool *cfg_changed_p)
6361 : 2844423 : : dom_walker (CDI_DOMINATORS), m_last_result_set (),
6362 : 948141 : m_cfg_changed_p (cfg_changed_p) {}
6363 : :
6364 : : /* The actual actions performed in the walk. */
6365 : :
6366 : : void after_dom_children (basic_block) final override;
6367 : :
6368 : : /* Set of results of chains of multiply and add statement combinations that
6369 : : were not transformed into FMAs because of active deferring. */
6370 : : hash_set<tree> m_last_result_set;
6371 : :
6372 : : /* Pointer to a flag of the user that needs to be set if CFG has been
6373 : : modified. */
6374 : : bool *m_cfg_changed_p;
6375 : : };
6376 : :
6377 : : void
6378 : 10487442 : math_opts_dom_walker::after_dom_children (basic_block bb)
6379 : : {
6380 : 10487442 : gimple_stmt_iterator gsi;
6381 : :
6382 : 10487442 : fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
6383 : :
6384 : 14947121 : for (gphi_iterator psi_next, psi = gsi_start_phis (bb); !gsi_end_p (psi);
6385 : 4459679 : psi = psi_next)
6386 : : {
6387 : 4459679 : psi_next = psi;
6388 : 4459679 : gsi_next (&psi_next);
6389 : :
6390 : 4459679 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
6391 : 4459679 : gphi *phi = psi.phi ();
6392 : :
6393 : 4459679 : if (match_saturation_add (&gsi, phi)
6394 : 4459662 : || match_saturation_sub (&gsi, phi)
6395 : 8919331 : || match_saturation_trunc (&gsi, phi))
6396 : 27 : remove_phi_node (&psi, /* release_lhs_p */ false);
6397 : : }
6398 : :
6399 : 91136166 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
6400 : : {
6401 : 80648724 : gimple *stmt = gsi_stmt (gsi);
6402 : 80648724 : enum tree_code code;
6403 : :
6404 : 80648724 : if (is_gimple_assign (stmt))
6405 : : {
6406 : 21391103 : code = gimple_assign_rhs_code (stmt);
6407 : 21391103 : switch (code)
6408 : : {
6409 : 704573 : case MULT_EXPR:
6410 : 704573 : if (!convert_mult_to_widen (stmt, &gsi)
6411 : 694341 : && !convert_expand_mult_copysign (stmt, &gsi)
6412 : 1398868 : && convert_mult_to_fma (stmt,
6413 : : gimple_assign_rhs1 (stmt),
6414 : : gimple_assign_rhs2 (stmt),
6415 : : &fma_state))
6416 : : {
6417 : 17266 : gsi_remove (&gsi, true);
6418 : 17266 : release_defs (stmt);
6419 : 17266 : continue;
6420 : : }
6421 : 687307 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6422 : 687307 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6423 : 687307 : break;
6424 : :
6425 : 2233365 : case PLUS_EXPR:
6426 : 2233365 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6427 : 2233365 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6428 : : /* fall-through */
6429 : 2532286 : case MINUS_EXPR:
6430 : 2532286 : if (!convert_plusminus_to_widen (&gsi, stmt, code))
6431 : : {
6432 : 2532286 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6433 : 2532286 : if (gsi_stmt (gsi) == stmt)
6434 : 2526088 : match_uaddc_usubc (&gsi, stmt, code);
6435 : : }
6436 : : break;
6437 : :
6438 : 35260 : case BIT_NOT_EXPR:
6439 : 35260 : if (match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p))
6440 : 170 : continue;
6441 : : break;
6442 : :
6443 : 54093 : case TRUNC_MOD_EXPR:
6444 : 54093 : convert_to_divmod (as_a<gassign *> (stmt));
6445 : 54093 : break;
6446 : :
6447 : 169495 : case RSHIFT_EXPR:
6448 : 169495 : convert_mult_to_highpart (as_a<gassign *> (stmt), &gsi);
6449 : 169495 : break;
6450 : :
6451 : 193567 : case BIT_IOR_EXPR:
6452 : 193567 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6453 : 193567 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6454 : : /* fall-through */
6455 : 220905 : case BIT_XOR_EXPR:
6456 : 220905 : match_uaddc_usubc (&gsi, stmt, code);
6457 : 220905 : break;
6458 : :
6459 : 304550 : case EQ_EXPR:
6460 : 304550 : case NE_EXPR:
6461 : 304550 : case LE_EXPR:
6462 : 304550 : case GT_EXPR:
6463 : 304550 : match_single_bit_test (&gsi, stmt);
6464 : 304550 : break;
6465 : :
6466 : 394361 : case COND_EXPR:
6467 : 394361 : case BIT_AND_EXPR:
6468 : 394361 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6469 : 394361 : break;
6470 : :
6471 : 2397963 : case NOP_EXPR:
6472 : 2397963 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6473 : 2397963 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6474 : 2397963 : break;
6475 : :
6476 : : default:;
6477 : : }
6478 : : }
6479 : 59257621 : else if (is_gimple_call (stmt))
6480 : : {
6481 : 4734826 : switch (gimple_call_combined_fn (stmt))
6482 : : {
6483 : 474 : CASE_CFN_POW:
6484 : 474 : if (gimple_call_lhs (stmt)
6485 : 434 : && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
6486 : 228 : && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
6487 : : &dconst2)
6488 : 474 : && convert_mult_to_fma (stmt,
6489 : : gimple_call_arg (stmt, 0),
6490 : : gimple_call_arg (stmt, 0),
6491 : : &fma_state))
6492 : : {
6493 : 0 : unlink_stmt_vdef (stmt);
6494 : 0 : if (gsi_remove (&gsi, true)
6495 : 0 : && gimple_purge_dead_eh_edges (bb))
6496 : 0 : *m_cfg_changed_p = true;
6497 : 0 : release_defs (stmt);
6498 : 0 : continue;
6499 : : }
6500 : : break;
6501 : :
6502 : 129 : case CFN_COND_MUL:
6503 : 129 : if (convert_mult_to_fma (stmt,
6504 : : gimple_call_arg (stmt, 1),
6505 : : gimple_call_arg (stmt, 2),
6506 : : &fma_state,
6507 : : gimple_call_arg (stmt, 0)))
6508 : :
6509 : : {
6510 : 84 : gsi_remove (&gsi, true);
6511 : 84 : release_defs (stmt);
6512 : 84 : continue;
6513 : : }
6514 : : break;
6515 : :
6516 : 0 : case CFN_COND_LEN_MUL:
6517 : 0 : if (convert_mult_to_fma (stmt,
6518 : : gimple_call_arg (stmt, 1),
6519 : : gimple_call_arg (stmt, 2),
6520 : : &fma_state,
6521 : : gimple_call_arg (stmt, 0),
6522 : : gimple_call_arg (stmt, 4),
6523 : : gimple_call_arg (stmt, 5)))
6524 : :
6525 : : {
6526 : 0 : gsi_remove (&gsi, true);
6527 : 0 : release_defs (stmt);
6528 : 0 : continue;
6529 : : }
6530 : : break;
6531 : :
6532 : 3630225 : case CFN_LAST:
6533 : 3630225 : cancel_fma_deferring (&fma_state);
6534 : 3630225 : break;
6535 : :
6536 : : default:
6537 : : break;
6538 : : }
6539 : : }
6540 : 54522795 : else if (gimple_code (stmt) == GIMPLE_COND)
6541 : : {
6542 : 4117502 : match_single_bit_test (&gsi, stmt);
6543 : 4117502 : optimize_spaceship (as_a <gcond *> (stmt));
6544 : : }
6545 : 80631204 : gsi_next (&gsi);
6546 : : }
6547 : 10487442 : if (fma_state.m_deferring_p
6548 : 7731690 : && fma_state.m_initial_phi)
6549 : : {
6550 : 297 : gcc_checking_assert (fma_state.m_last_result);
6551 : 297 : if (!last_fma_candidate_feeds_initial_phi (&fma_state,
6552 : : &m_last_result_set))
6553 : 172 : cancel_fma_deferring (&fma_state);
6554 : : else
6555 : 125 : m_last_result_set.add (fma_state.m_last_result);
6556 : : }
6557 : 10487442 : }
6558 : :
6559 : :
6560 : : unsigned int
6561 : 948141 : pass_optimize_widening_mul::execute (function *fun)
6562 : : {
6563 : 948141 : bool cfg_changed = false;
6564 : :
6565 : 948141 : memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
6566 : 948141 : calculate_dominance_info (CDI_DOMINATORS);
6567 : 948141 : renumber_gimple_stmt_uids (cfun);
6568 : :
6569 : 948141 : math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6570 : :
6571 : 948141 : statistics_counter_event (fun, "widening multiplications inserted",
6572 : : widen_mul_stats.widen_mults_inserted);
6573 : 948141 : statistics_counter_event (fun, "widening maccs inserted",
6574 : : widen_mul_stats.maccs_inserted);
6575 : 948141 : statistics_counter_event (fun, "fused multiply-adds inserted",
6576 : : widen_mul_stats.fmas_inserted);
6577 : 948141 : statistics_counter_event (fun, "divmod calls inserted",
6578 : : widen_mul_stats.divmod_calls_inserted);
6579 : 948141 : statistics_counter_event (fun, "highpart multiplications inserted",
6580 : : widen_mul_stats.highpart_mults_inserted);
6581 : :
6582 : 948141 : return cfg_changed ? TODO_cleanup_cfg : 0;
6583 : : }
6584 : :
6585 : : } // anon namespace
6586 : :
6587 : : gimple_opt_pass *
6588 : 285081 : make_pass_optimize_widening_mul (gcc::context *ctxt)
6589 : : {
6590 : 285081 : return new pass_optimize_widening_mul (ctxt);
6591 : : }
|