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 : 323619 : is_division_by (gimple *use_stmt, tree def)
353 : : {
354 : 323619 : return is_gimple_assign (use_stmt)
355 : 214475 : && 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 : 324472 : && !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 : 319938 : is_mult_by (gimple *use_stmt, tree def, tree a)
367 : : {
368 : 319938 : if (gimple_code (use_stmt) == GIMPLE_ASSIGN
369 : 319938 : && 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 : 319893 : 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 : 196537 : execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
756 : : {
757 : 196537 : use_operand_p use_p, square_use_p;
758 : 196537 : imm_use_iterator use_iter, square_use_iter;
759 : 196537 : tree square_def;
760 : 196537 : struct occurrence *occ;
761 : 196537 : int count = 0;
762 : 196537 : int threshold;
763 : 196537 : int square_recip_count = 0;
764 : 196537 : int sqrt_recip_count = 0;
765 : :
766 : 196537 : gcc_assert (FLOAT_TYPE_P (TREE_TYPE (def)) && TREE_CODE (def) == SSA_NAME);
767 : 196537 : 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 : 196537 : gimple *def_stmt = SSA_NAME_DEF_STMT (def);
778 : :
779 : 196537 : if (is_gimple_assign (def_stmt)
780 : 146557 : && gimple_assign_rhs_code (def_stmt) == MULT_EXPR
781 : 35913 : && TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
782 : 232372 : && 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 : 516361 : FOR_EACH_IMM_USE_FAST (use_p, use_iter, def)
795 : : {
796 : 319824 : gimple *use_stmt = USE_STMT (use_p);
797 : 319824 : if (is_division_by (use_stmt, def))
798 : : {
799 : 610 : register_division_in (gimple_bb (use_stmt), 2);
800 : 610 : count++;
801 : : }
802 : :
803 : 319824 : 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 : 196537 : square_recip_count /= 2;
821 : :
822 : : /* If it is more profitable to optimize 1 / x, don't optimize 1 / (x * x). */
823 : 196537 : 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 : 196523 : 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 : 196497 : out:
868 : 197128 : for (occ = occ_head; occ; )
869 : 591 : occ = free_bb (occ);
870 : :
871 : 196537 : occ_head = NULL;
872 : 196537 : }
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 : 284673 : pass_cse_reciprocals (gcc::context *ctxt)
921 : 569346 : : gimple_opt_pass (pass_data_cse_reciprocals, ctxt)
922 : : {}
923 : :
924 : : /* opt_pass methods: */
925 : 1024172 : bool gate (function *) final override
926 : : {
927 : 1024172 : return optimize && flag_reciprocal_math;
928 : : }
929 : : unsigned int execute (function *) final override;
930 : :
931 : : }; // class pass_cse_reciprocals
932 : :
933 : : unsigned int
934 : 8643 : pass_cse_reciprocals::execute (function *fun)
935 : : {
936 : 8643 : basic_block bb;
937 : 8643 : tree arg;
938 : :
939 : 8643 : occ_pool = new object_allocator<occurrence> ("dominators for recip");
940 : :
941 : 8643 : memset (&reciprocal_stats, 0, sizeof (reciprocal_stats));
942 : 8643 : calculate_dominance_info (CDI_DOMINATORS);
943 : 8643 : calculate_dominance_info (CDI_POST_DOMINATORS);
944 : :
945 : 8643 : if (flag_checking)
946 : 96527 : FOR_EACH_BB_FN (bb, fun)
947 : 87884 : gcc_assert (!bb->aux);
948 : :
949 : 21326 : for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg))
950 : 20116 : if (FLOAT_TYPE_P (TREE_TYPE (arg))
951 : 13768 : && 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 : 96527 : FOR_EACH_BB_FN (bb, fun)
959 : : {
960 : 87884 : tree def;
961 : :
962 : 206247 : for (gphi_iterator gsi = gsi_start_phis (bb); !gsi_end_p (gsi);
963 : 118363 : gsi_next (&gsi))
964 : : {
965 : 118363 : gphi *phi = gsi.phi ();
966 : 118363 : def = PHI_RESULT (phi);
967 : 118363 : if (! virtual_operand_p (def)
968 : 118363 : && FLOAT_TYPE_P (TREE_TYPE (def)))
969 : 35406 : execute_cse_reciprocals_1 (NULL, def);
970 : : }
971 : :
972 : 1330053 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
973 : 1242169 : gsi_next (&gsi))
974 : : {
975 : 1242169 : gimple *stmt = gsi_stmt (gsi);
976 : :
977 : 2484338 : if (gimple_has_lhs (stmt)
978 : 771265 : && (def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF)) != NULL
979 : 729898 : && FLOAT_TYPE_P (TREE_TYPE (def))
980 : 177625 : && TREE_CODE (def) == SSA_NAME)
981 : : {
982 : 155792 : execute_cse_reciprocals_1 (&gsi, def);
983 : 155792 : stmt = gsi_stmt (gsi);
984 : 155792 : if (flag_unsafe_math_optimizations
985 : 155763 : && is_gimple_assign (stmt)
986 : 146530 : && gimple_assign_lhs (stmt) == def
987 : 146528 : && !stmt_can_throw_internal (cfun, stmt)
988 : 302276 : && gimple_assign_rhs_code (stmt) == RDIV_EXPR)
989 : 538 : optimize_recip_sqrt (&gsi, def);
990 : : }
991 : : }
992 : :
993 : 87884 : 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 : 1314722 : for (gimple_stmt_iterator gsi = gsi_after_labels (bb); !gsi_end_p (gsi);
998 : 1232197 : gsi_next (&gsi))
999 : : {
1000 : 1232197 : gimple *stmt = gsi_stmt (gsi);
1001 : :
1002 : 1232197 : if (is_gimple_assign (stmt)
1003 : 1232197 : && 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 : 8643 : statistics_counter_event (fun, "reciprocal divs inserted",
1098 : : reciprocal_stats.rdivs_inserted);
1099 : 8643 : statistics_counter_event (fun, "reciprocal functions inserted",
1100 : : reciprocal_stats.rfuncs_inserted);
1101 : :
1102 : 8643 : free_dominance_info (CDI_DOMINATORS);
1103 : 8643 : free_dominance_info (CDI_POST_DOMINATORS);
1104 : 17286 : delete occ_pool;
1105 : 8643 : return 0;
1106 : : }
1107 : :
1108 : : } // anon namespace
1109 : :
1110 : : gimple_opt_pass *
1111 : 284673 : make_pass_cse_reciprocals (gcc::context *ctxt)
1112 : : {
1113 : 284673 : 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 : 17035 : build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc,
1632 : : tree type, tree val)
1633 : : {
1634 : 17035 : tree result = make_ssa_name (type);
1635 : 17035 : gassign *stmt = gimple_build_assign (result, NOP_EXPR, val);
1636 : 17035 : gimple_set_location (stmt, loc);
1637 : 17035 : gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
1638 : 17035 : 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 : 284673 : pass_cse_sincos (gcc::context *ctxt)
2204 : 569346 : : gimple_opt_pass (pass_data_cse_sincos, ctxt)
2205 : : {}
2206 : :
2207 : : /* opt_pass methods: */
2208 : 1024172 : bool gate (function *) final override
2209 : : {
2210 : 1024172 : return optimize;
2211 : : }
2212 : :
2213 : : unsigned int execute (function *) final override;
2214 : :
2215 : : }; // class pass_cse_sincos
2216 : :
2217 : : unsigned int
2218 : 1024150 : pass_cse_sincos::execute (function *fun)
2219 : : {
2220 : 1024150 : basic_block bb;
2221 : 1024150 : bool cfg_changed = false;
2222 : :
2223 : 1024150 : calculate_dominance_info (CDI_DOMINATORS);
2224 : 1024150 : memset (&sincos_stats, 0, sizeof (sincos_stats));
2225 : :
2226 : 11253101 : FOR_EACH_BB_FN (bb, fun)
2227 : : {
2228 : 10228951 : gimple_stmt_iterator gsi;
2229 : :
2230 : 92963826 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2231 : : {
2232 : 82734875 : gimple *stmt = gsi_stmt (gsi);
2233 : :
2234 : 82734875 : if (is_gimple_call (stmt)
2235 : 82734875 : && gimple_call_lhs (stmt))
2236 : : {
2237 : 2013466 : tree arg;
2238 : 2013466 : 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 : 1024150 : statistics_counter_event (fun, "sincos statements inserted",
2262 : : sincos_stats.inserted);
2263 : 1024150 : statistics_counter_event (fun, "conv statements removed",
2264 : : sincos_stats.conv_removed);
2265 : :
2266 : 1024150 : return cfg_changed ? TODO_cleanup_cfg : 0;
2267 : : }
2268 : :
2269 : : } // anon namespace
2270 : :
2271 : : gimple_opt_pass *
2272 : 284673 : make_pass_cse_sincos (gcc::context *ctxt)
2273 : : {
2274 : 284673 : 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 : 284673 : pass_expand_pow (gcc::context *ctxt)
2298 : 569346 : : gimple_opt_pass (pass_data_expand_pow, ctxt)
2299 : : {}
2300 : :
2301 : : /* opt_pass methods: */
2302 : 1024172 : bool gate (function *) final override
2303 : : {
2304 : 1024172 : return optimize;
2305 : : }
2306 : :
2307 : : unsigned int execute (function *) final override;
2308 : :
2309 : : }; // class pass_expand_pow
2310 : :
2311 : : unsigned int
2312 : 1024167 : pass_expand_pow::execute (function *fun)
2313 : : {
2314 : 1024167 : basic_block bb;
2315 : 1024167 : bool cfg_changed = false;
2316 : :
2317 : 1024167 : calculate_dominance_info (CDI_DOMINATORS);
2318 : :
2319 : 10478607 : FOR_EACH_BB_FN (bb, fun)
2320 : : {
2321 : 9454440 : gimple_stmt_iterator gsi;
2322 : 9454440 : bool cleanup_eh = false;
2323 : :
2324 : 90132722 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi); gsi_next (&gsi))
2325 : : {
2326 : 80678282 : 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 : 80678282 : cleanup_eh = false;
2332 : :
2333 : 80678282 : if (is_gimple_call (stmt)
2334 : 80678282 : && gimple_call_lhs (stmt))
2335 : : {
2336 : 1987594 : tree arg0, arg1, result;
2337 : 1987594 : HOST_WIDE_INT n;
2338 : 1987594 : location_t loc;
2339 : :
2340 : 1987594 : 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 : 80679456 : if (gimple_vdef (stmt))
2407 : 0 : release_ssa_name (gimple_vdef (stmt));
2408 : : }
2409 : : break;
2410 : :
2411 : 211 : default:;
2412 : : }
2413 : : }
2414 : : }
2415 : 9454440 : if (cleanup_eh)
2416 : 1 : cfg_changed |= gimple_purge_dead_eh_edges (bb);
2417 : : }
2418 : :
2419 : 1024167 : return cfg_changed ? TODO_cleanup_cfg : 0;
2420 : : }
2421 : :
2422 : : } // anon namespace
2423 : :
2424 : : gimple_opt_pass *
2425 : 284673 : make_pass_expand_pow (gcc::context *ctxt)
2426 : : {
2427 : 284673 : 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 : 443396 : widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
2434 : : {
2435 : 443396 : enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
2436 : :
2437 : 443396 : if (TREE_CODE (result_type) == INTEGER_TYPE)
2438 : : {
2439 : 443396 : tree op_type;
2440 : 443396 : tree inner_op_type;
2441 : :
2442 : 443396 : if (!CONVERT_EXPR_CODE_P (rhs_code))
2443 : : return false;
2444 : :
2445 : 177705 : 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 : 177705 : 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 : 896785 : is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out,
2483 : : tree *new_rhs_out)
2484 : : {
2485 : 896785 : gimple *stmt;
2486 : 896785 : tree type1, rhs1;
2487 : :
2488 : 896785 : 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 : 740478 : if (TREE_CODE (type) == INTEGER_TYPE
2494 : 740478 : && (TYPE_PRECISION (type) & 1) == 0
2495 : 1480956 : && int_mode_for_size (TYPE_PRECISION (type) / 2, 1).exists ())
2496 : : {
2497 : 734698 : unsigned int prec = TYPE_PRECISION (type);
2498 : 734698 : unsigned int hprec = prec / 2;
2499 : 734698 : wide_int bits = wide_int::from (tree_nonzero_bits (rhs), prec,
2500 : 1469396 : TYPE_SIGN (TREE_TYPE (rhs)));
2501 : 734698 : if (TYPE_UNSIGNED (type)
2502 : 1271322 : && wi::bit_and (bits, wi::mask (hprec, true, prec)) == 0)
2503 : : {
2504 : 146438 : *type_out = build_nonstandard_integer_type (hprec, true);
2505 : : /* X & MODE_MASK can be simplified to (T)X. */
2506 : 146438 : stmt = SSA_NAME_DEF_STMT (rhs);
2507 : 292876 : if (is_gimple_assign (stmt)
2508 : 127702 : && gimple_assign_rhs_code (stmt) == BIT_AND_EXPR
2509 : 16771 : && TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
2510 : 179380 : && wide_int::from (wi::to_wide (gimple_assign_rhs2 (stmt)),
2511 : 16471 : prec, TYPE_SIGN (TREE_TYPE (rhs)))
2512 : 195851 : == wi::mask (hprec, false, prec))
2513 : 14638 : *new_rhs_out = gimple_assign_rhs1 (stmt);
2514 : : else
2515 : 131800 : *new_rhs_out = rhs;
2516 : 146438 : return true;
2517 : : }
2518 : 588260 : else if (!TYPE_UNSIGNED (type)
2519 : 786334 : && wi::bit_and (bits, wi::mask (hprec - 1, true, prec)) == 0)
2520 : : {
2521 : 26539 : *type_out = build_nonstandard_integer_type (hprec, false);
2522 : 26539 : *new_rhs_out = rhs;
2523 : 26539 : return true;
2524 : : }
2525 : 734698 : }
2526 : :
2527 : 567501 : stmt = SSA_NAME_DEF_STMT (rhs);
2528 : 567501 : if (is_gimple_assign (stmt))
2529 : : {
2530 : :
2531 : 443396 : if (widening_mult_conversion_strippable_p (type, stmt))
2532 : : {
2533 : 176548 : rhs1 = gimple_assign_rhs1 (stmt);
2534 : :
2535 : 176548 : 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 : 567501 : type1 = TREE_TYPE (rhs1);
2549 : :
2550 : 567501 : if (TREE_CODE (type1) != TREE_CODE (type)
2551 : 567501 : || TYPE_PRECISION (type1) * 2 > TYPE_PRECISION (type))
2552 : : return false;
2553 : :
2554 : 58019 : *new_rhs_out = rhs1;
2555 : 58019 : *type_out = type1;
2556 : 58019 : return true;
2557 : : }
2558 : :
2559 : 156307 : if (TREE_CODE (rhs) == INTEGER_CST)
2560 : : {
2561 : 156307 : *new_rhs_out = rhs;
2562 : 156307 : *type_out = NULL;
2563 : 156307 : 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 : 700237 : is_widening_mult_p (gimple *stmt,
2577 : : tree *type1_out, tree *rhs1_out,
2578 : : tree *type2_out, tree *rhs2_out)
2579 : : {
2580 : 700237 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
2581 : :
2582 : 700237 : if (TREE_CODE (type) == INTEGER_TYPE)
2583 : : {
2584 : 700237 : if (TYPE_OVERFLOW_TRAPS (type))
2585 : : return false;
2586 : : }
2587 : 0 : else if (TREE_CODE (type) != FIXED_POINT_TYPE)
2588 : : return false;
2589 : :
2590 : 700209 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs1 (stmt), type1_out,
2591 : : rhs1_out))
2592 : : return false;
2593 : :
2594 : 196576 : if (!is_widening_mult_rhs_p (type, gimple_assign_rhs2 (stmt), type2_out,
2595 : : rhs2_out))
2596 : : return false;
2597 : :
2598 : 190727 : 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 : 190727 : if (*type2_out == NULL)
2606 : : {
2607 : 156307 : if (!int_fits_type_p (*rhs2_out, *type1_out))
2608 : : return false;
2609 : 151613 : *type2_out = *type1_out;
2610 : : }
2611 : :
2612 : : /* Ensure that the larger of the two operands comes first. */
2613 : 186033 : 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 : 151690 : is_copysign_call_with_1 (gimple *call)
2626 : : {
2627 : 156763 : 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 : 693403 : convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
2668 : : {
2669 : 693403 : tree treeop0, treeop1, lhs, type;
2670 : 693403 : location_t loc = gimple_location (stmt);
2671 : 693403 : lhs = gimple_assign_lhs (stmt);
2672 : 693403 : treeop0 = gimple_assign_rhs1 (stmt);
2673 : 693403 : treeop1 = gimple_assign_rhs2 (stmt);
2674 : 693403 : type = TREE_TYPE (lhs);
2675 : 693403 : machine_mode mode = TYPE_MODE (type);
2676 : :
2677 : 693403 : if (HONOR_SNANS (type))
2678 : : return false;
2679 : :
2680 : 693311 : if (TREE_CODE (treeop0) == SSA_NAME && TREE_CODE (treeop1) == SSA_NAME)
2681 : : {
2682 : 209461 : gimple *call0 = SSA_NAME_DEF_STMT (treeop0);
2683 : 209461 : if (!has_single_use (treeop0) || !is_copysign_call_with_1 (call0))
2684 : : {
2685 : 209435 : call0 = SSA_NAME_DEF_STMT (treeop1);
2686 : 209435 : if (!has_single_use (treeop1) || !is_copysign_call_with_1 (call0))
2687 : 209415 : 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 : 703639 : convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
2714 : : {
2715 : 703639 : tree lhs, rhs1, rhs2, type, type1, type2;
2716 : 703639 : enum insn_code handler;
2717 : 703639 : scalar_int_mode to_mode, from_mode, actual_mode;
2718 : 703639 : optab op;
2719 : 703639 : int actual_precision;
2720 : 703639 : location_t loc = gimple_location (stmt);
2721 : 703639 : bool from_unsigned1, from_unsigned2;
2722 : :
2723 : 703639 : lhs = gimple_assign_lhs (stmt);
2724 : 703639 : type = TREE_TYPE (lhs);
2725 : 703639 : if (TREE_CODE (type) != INTEGER_TYPE)
2726 : : return false;
2727 : :
2728 : 567690 : 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 : 151351 : if ((TREE_CODE (rhs1) == SSA_NAME
2734 : 151351 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
2735 : 302701 : || (TREE_CODE (rhs2) == SSA_NAME
2736 : 23998 : && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2)))
2737 : : return false;
2738 : :
2739 : 151350 : to_mode = SCALAR_INT_TYPE_MODE (type);
2740 : 151350 : from_mode = SCALAR_INT_TYPE_MODE (type1);
2741 : 151350 : if (to_mode == from_mode)
2742 : : return false;
2743 : :
2744 : 151346 : from_unsigned1 = TYPE_UNSIGNED (type1);
2745 : 151346 : from_unsigned2 = TYPE_UNSIGNED (type2);
2746 : :
2747 : 151346 : if (from_unsigned1 && from_unsigned2)
2748 : : op = umul_widen_optab;
2749 : 56606 : else if (!from_unsigned1 && !from_unsigned2)
2750 : : op = smul_widen_optab;
2751 : : else
2752 : 1907 : op = usmul_widen_optab;
2753 : :
2754 : 151346 : handler = find_widening_optab_handler_and_mode (op, to_mode, from_mode,
2755 : : &actual_mode);
2756 : :
2757 : 151346 : if (handler == CODE_FOR_nothing)
2758 : : {
2759 : 141110 : 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 : 87897 : if ((TYPE_UNSIGNED (type1)
2765 : 86178 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2766 : 87897 : || (TYPE_UNSIGNED (type2)
2767 : 1719 : && TYPE_PRECISION (type2) == GET_MODE_PRECISION (from_mode)))
2768 : : {
2769 : 87897 : if (!GET_MODE_WIDER_MODE (from_mode).exists (&from_mode)
2770 : 175794 : || GET_MODE_SIZE (to_mode) <= GET_MODE_SIZE (from_mode))
2771 : 87897 : 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 : 53213 : op = umul_widen_optab;
2789 : 53213 : handler = find_widening_optab_handler_and_mode (op, to_mode,
2790 : : from_mode,
2791 : : &actual_mode);
2792 : 53213 : 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 : 10236 : actual_precision = GET_MODE_PRECISION (actual_mode);
2800 : 10236 : if (2 * actual_precision > TYPE_PRECISION (type))
2801 : : return false;
2802 : 10236 : if (actual_precision != TYPE_PRECISION (type1)
2803 : 10236 : || 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 : 10236 : if (!useless_type_conversion_p (type1, TREE_TYPE (rhs1)))
2816 : : {
2817 : 9515 : if (TREE_CODE (rhs1) == INTEGER_CST)
2818 : 0 : rhs1 = fold_convert (type1, rhs1);
2819 : : else
2820 : 9515 : rhs1 = build_and_insert_cast (gsi, loc, type1, rhs1);
2821 : : }
2822 : 10236 : if (actual_precision != TYPE_PRECISION (type2)
2823 : 10236 : || 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 : 10236 : if (!useless_type_conversion_p (type2, TREE_TYPE (rhs2)))
2836 : : {
2837 : 9706 : if (TREE_CODE (rhs2) == INTEGER_CST)
2838 : 2202 : rhs2 = fold_convert (type2, rhs2);
2839 : : else
2840 : 7504 : rhs2 = build_and_insert_cast (gsi, loc, type2, rhs2);
2841 : : }
2842 : :
2843 : 10236 : gimple_assign_set_rhs1 (stmt, rhs1);
2844 : 10236 : gimple_assign_set_rhs2 (stmt, rhs2);
2845 : 10236 : gimple_assign_set_rhs_code (stmt, WIDEN_MULT_EXPR);
2846 : 10236 : update_stmt (stmt);
2847 : 10236 : widen_mul_stats.widen_mults_inserted++;
2848 : 10236 : 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 : 2514966 : convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt,
2859 : : enum tree_code code)
2860 : : {
2861 : 2514966 : gimple *rhs1_stmt = NULL, *rhs2_stmt = NULL;
2862 : 2514966 : gimple *conv1_stmt = NULL, *conv2_stmt = NULL, *conv_stmt;
2863 : 2514966 : tree type, type1, type2, optype;
2864 : 2514966 : tree lhs, rhs1, rhs2, mult_rhs1, mult_rhs2, add_rhs;
2865 : 2514966 : enum tree_code rhs1_code = ERROR_MARK, rhs2_code = ERROR_MARK;
2866 : 2514966 : optab this_optab;
2867 : 2514966 : enum tree_code wmult_code;
2868 : 2514966 : enum insn_code handler;
2869 : 2514966 : scalar_mode to_mode, from_mode, actual_mode;
2870 : 2514966 : location_t loc = gimple_location (stmt);
2871 : 2514966 : int actual_precision;
2872 : 2514966 : bool from_unsigned1, from_unsigned2;
2873 : :
2874 : 2514966 : lhs = gimple_assign_lhs (stmt);
2875 : 2514966 : type = TREE_TYPE (lhs);
2876 : 2514966 : if ((TREE_CODE (type) != INTEGER_TYPE
2877 : 396015 : && TREE_CODE (type) != FIXED_POINT_TYPE)
2878 : 2514966 : || !type_has_mode_precision_p (type))
2879 : 397679 : return false;
2880 : :
2881 : 2117287 : if (code == MINUS_EXPR)
2882 : : wmult_code = WIDEN_MULT_MINUS_EXPR;
2883 : : else
2884 : 1876934 : wmult_code = WIDEN_MULT_PLUS_EXPR;
2885 : :
2886 : 2117287 : rhs1 = gimple_assign_rhs1 (stmt);
2887 : 2117287 : rhs2 = gimple_assign_rhs2 (stmt);
2888 : :
2889 : 2117287 : if (TREE_CODE (rhs1) == SSA_NAME)
2890 : : {
2891 : 2081857 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2892 : 2081857 : if (is_gimple_assign (rhs1_stmt))
2893 : 1213166 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2894 : : }
2895 : :
2896 : 2117287 : if (TREE_CODE (rhs2) == SSA_NAME)
2897 : : {
2898 : 762487 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2899 : 762487 : if (is_gimple_assign (rhs2_stmt))
2900 : 585183 : 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 : 2117287 : if (CONVERT_EXPR_CODE_P (rhs1_code))
2909 : : {
2910 : 405757 : conv1_stmt = rhs1_stmt;
2911 : 405757 : rhs1 = gimple_assign_rhs1 (rhs1_stmt);
2912 : 405757 : if (TREE_CODE (rhs1) == SSA_NAME)
2913 : : {
2914 : 340913 : rhs1_stmt = SSA_NAME_DEF_STMT (rhs1);
2915 : 340913 : if (is_gimple_assign (rhs1_stmt))
2916 : 192956 : rhs1_code = gimple_assign_rhs_code (rhs1_stmt);
2917 : : }
2918 : : else
2919 : : return false;
2920 : : }
2921 : 2052443 : if (CONVERT_EXPR_CODE_P (rhs2_code))
2922 : : {
2923 : 184659 : conv2_stmt = rhs2_stmt;
2924 : 184659 : rhs2 = gimple_assign_rhs1 (rhs2_stmt);
2925 : 184659 : if (TREE_CODE (rhs2) == SSA_NAME)
2926 : : {
2927 : 172891 : rhs2_stmt = SSA_NAME_DEF_STMT (rhs2);
2928 : 172891 : if (is_gimple_assign (rhs2_stmt))
2929 : 109912 : 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 : 2040675 : if (code == PLUS_EXPR
2947 : 1806248 : && (rhs1_code == MULT_EXPR || rhs1_code == WIDEN_MULT_EXPR))
2948 : : {
2949 : 125507 : if (!has_single_use (rhs1)
2950 : 73316 : || gimple_bb (rhs1_stmt) != gimple_bb (stmt)
2951 : 190451 : || !is_widening_mult_p (rhs1_stmt, &type1, &mult_rhs1,
2952 : : &type2, &mult_rhs2))
2953 : 105623 : return false;
2954 : : add_rhs = rhs2;
2955 : : conv_stmt = conv1_stmt;
2956 : : }
2957 : 1915168 : else if (rhs2_code == MULT_EXPR || rhs2_code == WIDEN_MULT_EXPR)
2958 : : {
2959 : 121850 : if (!has_single_use (rhs2)
2960 : 75929 : || gimple_bb (rhs2_stmt) != gimple_bb (stmt)
2961 : 189453 : || !is_widening_mult_p (rhs2_stmt, &type1, &mult_rhs1,
2962 : : &type2, &mult_rhs2))
2963 : 107052 : return false;
2964 : : add_rhs = rhs1;
2965 : : conv_stmt = conv2_stmt;
2966 : : }
2967 : : else
2968 : : return false;
2969 : :
2970 : 34682 : to_mode = SCALAR_TYPE_MODE (type);
2971 : 34682 : from_mode = SCALAR_TYPE_MODE (type1);
2972 : 34682 : if (to_mode == from_mode)
2973 : : return false;
2974 : :
2975 : 34679 : from_unsigned1 = TYPE_UNSIGNED (type1);
2976 : 34679 : from_unsigned2 = TYPE_UNSIGNED (type2);
2977 : 34679 : optype = type1;
2978 : :
2979 : : /* There's no such thing as a mixed sign madd yet, so use a wider mode. */
2980 : 34679 : 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 : 55 : && TYPE_PRECISION (type1) == GET_MODE_PRECISION (from_mode))
2989 : 906 : || (from_unsigned2
2990 : 851 : && 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 : 33809 : if (conv_stmt)
3007 : : {
3008 : : /* We use the original, unmodified data types for this. */
3009 : 740 : tree from_type = TREE_TYPE (gimple_assign_rhs1 (conv_stmt));
3010 : 740 : tree to_type = TREE_TYPE (gimple_assign_lhs (conv_stmt));
3011 : 740 : int data_size = TYPE_PRECISION (type1) + TYPE_PRECISION (type2);
3012 : 740 : bool is_unsigned = TYPE_UNSIGNED (type1) && TYPE_UNSIGNED (type2);
3013 : :
3014 : 740 : 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 : 740 : 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 : 33470 : this_optab = optab_for_tree_code (wmult_code, optype, optab_default);
3034 : 33470 : handler = find_widening_optab_handler_and_mode (this_optab, to_mode,
3035 : : from_mode, &actual_mode);
3036 : :
3037 : 33470 : 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 : 18296 : convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
3100 : : {
3101 : 18296 : tree type = TREE_TYPE (mul_result);
3102 : 18296 : gimple *use_stmt;
3103 : 18296 : imm_use_iterator imm_iter;
3104 : 18296 : gcall *fma_stmt;
3105 : :
3106 : 36663 : FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, mul_result)
3107 : : {
3108 : 18367 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
3109 : 18367 : tree addop, mulop1 = op1, result = mul_result;
3110 : 18367 : bool negate_p = false;
3111 : 18367 : gimple_seq seq = NULL;
3112 : :
3113 : 18367 : if (is_gimple_debug (use_stmt))
3114 : 0 : continue;
3115 : :
3116 : 18367 : if (is_gimple_assign (use_stmt)
3117 : 18367 : && 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 : 18367 : tree cond, else_value, ops[3], len, bias;
3132 : 18367 : tree_code code;
3133 : 18367 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code,
3134 : : ops, &else_value,
3135 : : &len, &bias))
3136 : 0 : gcc_unreachable ();
3137 : 18367 : addop = ops[0] == result ? ops[1] : ops[0];
3138 : :
3139 : 18367 : 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 : 18367 : if (negate_p)
3150 : 4008 : mulop1 = gimple_build (&seq, NEGATE_EXPR, type, mulop1);
3151 : :
3152 : 18367 : if (seq)
3153 : 6205 : gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
3154 : :
3155 : 18367 : 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 : 18367 : 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 : 18273 : fma_stmt = gimple_build_call_internal (IFN_FMA, 3, mulop1, op2, addop);
3164 : 18367 : gimple_set_lhs (fma_stmt, gimple_get_lhs (use_stmt));
3165 : 18367 : gimple_call_set_nothrow (fma_stmt, !stmt_can_throw_internal (cfun,
3166 : : use_stmt));
3167 : 18367 : 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 : 18367 : gimple *orig_stmt = gsi_stmt (gsi);
3171 : 18367 : 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 : 18367 : 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 : 18367 : orig_stmt = gsi_stmt (gsi);
3188 : 18367 : use_operand_p use_p;
3189 : 18367 : gimple *neg_stmt;
3190 : 18367 : if (is_gimple_call (orig_stmt)
3191 : 18367 : && gimple_call_internal_p (orig_stmt)
3192 : 18367 : && gimple_call_lhs (orig_stmt)
3193 : 18367 : && TREE_CODE (gimple_call_lhs (orig_stmt)) == SSA_NAME
3194 : 18367 : && single_imm_use (gimple_call_lhs (orig_stmt), &use_p, &neg_stmt)
3195 : 13716 : && is_gimple_assign (neg_stmt)
3196 : 10729 : && gimple_assign_rhs_code (neg_stmt) == NEGATE_EXPR
3197 : 19720 : && !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 : 18367 : widen_mul_stats.fmas_inserted++;
3215 : 18296 : }
3216 : 18296 : }
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 : 10452151 : 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 : 10452151 : fma_deferring_state (bool perform_deferring)
3241 : 10452151 : : m_candidates (), m_mul_result_set (), m_initial_phi (NULL),
3242 : 10452151 : 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 : 3609035 : cancel_fma_deferring (fma_deferring_state *state)
3271 : : {
3272 : 3609035 : if (!state->m_deferring_p)
3273 : : return;
3274 : :
3275 : 2631467 : for (unsigned i = 0; i < state->m_candidates.length (); i++)
3276 : : {
3277 : 946 : if (dump_file && (dump_flags & TDF_DETAILS))
3278 : 0 : fprintf (dump_file, "Generating deferred FMA\n");
3279 : :
3280 : 946 : const fma_transformation_info &fti = state->m_candidates[i];
3281 : 946 : convert_mult_to_fma_1 (fti.mul_result, fti.op1, fti.op2);
3282 : :
3283 : 946 : gimple_stmt_iterator gsi = gsi_for_stmt (fti.mul_stmt);
3284 : 946 : gsi_remove (&gsi, true);
3285 : 946 : release_defs (fti.mul_stmt);
3286 : : }
3287 : 2630521 : 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 : 4814 : result_of_phi (tree op)
3295 : : {
3296 : 0 : if (TREE_CODE (op) != SSA_NAME)
3297 : : return NULL;
3298 : :
3299 : 4769 : 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 : 289 : last_fma_candidate_feeds_initial_phi (fma_deferring_state *state,
3308 : : hash_set<tree> *last_result_set)
3309 : : {
3310 : 289 : ssa_op_iter iter;
3311 : 289 : use_operand_p use;
3312 : 617 : FOR_EACH_PHI_ARG (use, state->m_initial_phi, iter, SSA_OP_USE)
3313 : : {
3314 : 453 : tree t = USE_FROM_PTR (use);
3315 : 453 : if (t == state->m_last_result
3316 : 453 : || 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 : 693486 : 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 : 693486 : 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 : 693486 : if (!mul_result)
3351 : : return false;
3352 : 693486 : tree type = TREE_TYPE (mul_result);
3353 : 693486 : gimple *use_stmt, *neguse_stmt;
3354 : 693486 : use_operand_p use_p;
3355 : 693486 : imm_use_iterator imm_iter;
3356 : :
3357 : 592494 : if (FLOAT_TYPE_P (type)
3358 : 714438 : && flag_fp_contract_mode != FP_CONTRACT_FAST)
3359 : : return false;
3360 : :
3361 : : /* We don't want to do bitfield reduction ops. */
3362 : 688346 : if (INTEGRAL_TYPE_P (type)
3363 : 688346 : && (!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 : 688176 : optimization_type opt_type = bb_optimization_type (gimple_bb (mul_stmt));
3369 : 688176 : 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 : 23113 : if (has_zero_uses (mul_result))
3376 : : return false;
3377 : :
3378 : 23113 : bool check_defer
3379 : 23113 : = (state->m_deferring_p
3380 : 23113 : && maybe_le (tree_to_poly_int64 (TYPE_SIZE (type)),
3381 : 23113 : param_avoid_fma_max_bits));
3382 : 23113 : bool defer = check_defer;
3383 : 23113 : 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 : 23113 : if (ANY_INTEGRAL_TYPE_P (type)
3395 : 23113 : && !has_single_use (mul_result))
3396 : : return false;
3397 : :
3398 : 23113 : 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 : 42469 : FOR_EACH_IMM_USE_FAST (use_p, imm_iter, mul_result)
3406 : : {
3407 : 24048 : tree result = mul_result;
3408 : 24048 : bool negate_p = false;
3409 : :
3410 : 24048 : use_stmt = USE_STMT (use_p);
3411 : :
3412 : 24048 : 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 : 23642 : if (gimple_bb (use_stmt) != gimple_bb (mul_stmt))
3425 : 4692 : return false;
3426 : :
3427 : : /* A negate on the multiplication leads to FNMA. */
3428 : 22794 : if (is_gimple_assign (use_stmt)
3429 : 22794 : && 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 : 22794 : tree cond, else_value, ops[3], len, bias;
3462 : 22794 : tree_code code;
3463 : 22794 : if (!can_interpret_as_conditional_op_p (use_stmt, &cond, &code, ops,
3464 : : &else_value, &len, &bias))
3465 : : return false;
3466 : :
3467 : 20871 : 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 : 18972 : 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 : 18972 : if (mul_cond && cond != mul_cond)
3513 : : return false;
3514 : :
3515 : 18960 : 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 : 18950 : 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 : 18950 : && 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 : 18950 : 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 : 18950 : if (state->m_deferring_p
3550 : 18950 : && (state->m_mul_result_set.contains (ops[0])
3551 : 6116 : || state->m_mul_result_set.contains (ops[1])))
3552 : 0 : return false;
3553 : :
3554 : 18950 : if (check_defer)
3555 : : {
3556 : 5964 : tree use_lhs = gimple_get_lhs (use_stmt);
3557 : 5964 : 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 : 5964 : defer = false;
3564 : : }
3565 : : else
3566 : : {
3567 : 4814 : gcc_checking_assert (!state->m_initial_phi);
3568 : 4814 : gphi *phi;
3569 : 4814 : if (ops[0] == result)
3570 : 3047 : phi = result_of_phi (ops[1]);
3571 : : else
3572 : : {
3573 : 1767 : gcc_assert (ops[1] == result);
3574 : 1767 : phi = result_of_phi (ops[0]);
3575 : : }
3576 : :
3577 : : if (phi)
3578 : : {
3579 : 893 : state->m_initial_phi = phi;
3580 : 893 : defer = true;
3581 : : }
3582 : : else
3583 : : defer = false;
3584 : : }
3585 : :
3586 : 5964 : state->m_last_result = use_lhs;
3587 : 5964 : 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 : 18421 : if (defer)
3603 : : {
3604 : 1071 : fma_transformation_info fti;
3605 : 1071 : fti.mul_stmt = mul_stmt;
3606 : 1071 : fti.mul_result = mul_result;
3607 : 1071 : fti.op1 = op1;
3608 : 1071 : fti.op2 = op2;
3609 : 1071 : state->m_candidates.safe_push (fti);
3610 : 1071 : state->m_mul_result_set.add (mul_result);
3611 : :
3612 : 1071 : 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 : 1071 : 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 : 2811425 : arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt,
3835 : : tree maxval, tree *other)
3836 : : {
3837 : 2811425 : enum tree_code ccode = ERROR_MARK;
3838 : 2811425 : tree crhs1 = NULL_TREE, crhs2 = NULL_TREE;
3839 : 2811425 : enum tree_code code = gimple_assign_rhs_code (stmt);
3840 : 5589454 : tree lhs = gimple_assign_lhs (cast_stmt ? cast_stmt : stmt);
3841 : 2811425 : tree rhs1 = gimple_assign_rhs1 (stmt);
3842 : 2811425 : tree rhs2 = gimple_assign_rhs2 (stmt);
3843 : 2811425 : tree multop = NULL_TREE, divlhs = NULL_TREE;
3844 : 2811425 : gimple *cur_use_stmt = use_stmt;
3845 : :
3846 : 2811425 : if (code == MULT_EXPR)
3847 : : {
3848 : 631044 : if (!is_gimple_assign (use_stmt))
3849 : 630750 : return 0;
3850 : 507526 : if (gimple_assign_rhs_code (use_stmt) != TRUNC_DIV_EXPR)
3851 : : return 0;
3852 : 2546 : if (gimple_assign_rhs1 (use_stmt) != lhs)
3853 : : return 0;
3854 : 2483 : 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 : 2328 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
3864 : : multop = rhs2;
3865 : 2252 : 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 : 2180675 : if (gimple_code (cur_use_stmt) == GIMPLE_COND)
3894 : : {
3895 : 569915 : ccode = gimple_cond_code (cur_use_stmt);
3896 : 569915 : crhs1 = gimple_cond_lhs (cur_use_stmt);
3897 : 569915 : crhs2 = gimple_cond_rhs (cur_use_stmt);
3898 : : }
3899 : 1610760 : else if (is_gimple_assign (cur_use_stmt))
3900 : : {
3901 : 784535 : if (gimple_assign_rhs_class (cur_use_stmt) == GIMPLE_BINARY_RHS)
3902 : : {
3903 : 471892 : ccode = gimple_assign_rhs_code (cur_use_stmt);
3904 : 471892 : crhs1 = gimple_assign_rhs1 (cur_use_stmt);
3905 : 471892 : crhs2 = gimple_assign_rhs2 (cur_use_stmt);
3906 : : }
3907 : 312643 : else if (gimple_assign_rhs_code (cur_use_stmt) == COND_EXPR)
3908 : : {
3909 : 5020 : tree cond = gimple_assign_rhs1 (cur_use_stmt);
3910 : 5020 : 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 : 1041807 : if (maxval
3926 : 1041807 : && ccode == RSHIFT_EXPR
3927 : 105 : && crhs1 == lhs
3928 : 25 : && TREE_CODE (crhs2) == INTEGER_CST
3929 : 1041832 : && 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 : 1041791 : if (TREE_CODE_CLASS (ccode) != tcc_comparison)
3986 : : return 0;
3987 : :
3988 : 607830 : switch (ccode)
3989 : : {
3990 : 112900 : case GT_EXPR:
3991 : 112900 : case LE_EXPR:
3992 : 112900 : if (maxval)
3993 : : {
3994 : : /* r = a + b; r > maxval or r <= maxval */
3995 : 47 : if (crhs1 == lhs
3996 : 44 : && TREE_CODE (crhs2) == INTEGER_CST
3997 : 69 : && 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 : 112853 : if ((code == MINUS_EXPR && crhs1 == lhs && crhs2 == rhs1)
4004 : 112791 : || (code == PLUS_EXPR && (crhs1 == rhs1 || crhs1 == rhs2)
4005 : 8814 : && crhs2 == lhs))
4006 : 9208 : return ccode == GT_EXPR ? 1 : -1;
4007 : : /* r = ~a; b > r or b <= r. */
4008 : 103977 : 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 : 63641 : case LT_EXPR:
4016 : 63641 : case GE_EXPR:
4017 : 63641 : 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 : 63633 : if ((code == MINUS_EXPR && crhs1 == rhs1 && crhs2 == lhs)
4022 : 63493 : || (code == PLUS_EXPR && crhs1 == lhs
4023 : 27484 : && (crhs2 == rhs1 || crhs2 == rhs2)))
4024 : 3963 : return ccode == LT_EXPR ? 1 : -1;
4025 : : /* r = ~a; r < b or r >= b. */
4026 : 59722 : 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 : 431289 : case EQ_EXPR:
4034 : 431289 : 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 : 431289 : 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 : : extern bool gimple_unsigned_integer_sat_mul (tree, tree*, tree (*)(tree));
4068 : :
4069 : : extern bool gimple_signed_integer_sat_add (tree, tree*, tree (*)(tree));
4070 : : extern bool gimple_signed_integer_sat_sub (tree, tree*, tree (*)(tree));
4071 : : extern bool gimple_signed_integer_sat_trunc (tree, tree*, tree (*)(tree));
4072 : :
4073 : : static void
4074 : 150 : build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi,
4075 : : internal_fn fn, tree lhs,
4076 : : tree op_0, tree op_1)
4077 : : {
4078 : 150 : if (direct_internal_fn_supported_p (fn, TREE_TYPE (lhs), OPTIMIZE_FOR_BOTH))
4079 : : {
4080 : 150 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4081 : 150 : gimple_call_set_lhs (call, lhs);
4082 : 150 : gsi_replace (gsi, call, /* update_eh_info */ true);
4083 : : }
4084 : 150 : }
4085 : :
4086 : : static bool
4087 : 35 : build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi,
4088 : : internal_fn fn, tree lhs,
4089 : : tree op_0, tree op_1)
4090 : : {
4091 : 35 : if (!direct_internal_fn_supported_p (fn, TREE_TYPE (op_0), OPTIMIZE_FOR_BOTH))
4092 : : return false;
4093 : :
4094 : 27 : gcall *call = gimple_build_call_internal (fn, 2, op_0, op_1);
4095 : 27 : gimple_call_set_lhs (call, lhs);
4096 : 27 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4097 : :
4098 : 27 : return true;
4099 : : }
4100 : :
4101 : : /*
4102 : : * Try to match saturation unsigned add with assign.
4103 : : * _7 = _4 + _6;
4104 : : * _8 = _4 > _7;
4105 : : * _9 = (long unsigned int) _8;
4106 : : * _10 = -_9;
4107 : : * _12 = _7 | _10;
4108 : : * =>
4109 : : * _12 = .SAT_ADD (_4, _6);
4110 : : *
4111 : : * Try to match IMM=-1 saturation signed add with assign.
4112 : : * <bb 2> [local count: 1073741824]:
4113 : : * x.0_1 = (unsigned char) x_5(D);
4114 : : * _3 = -x.0_1;
4115 : : * _10 = (signed char) _3;
4116 : : * _8 = x_5(D) & _10;
4117 : : * if (_8 < 0)
4118 : : * goto <bb 4>; [1.40%]
4119 : : * else
4120 : : * goto <bb 3>; [98.60%]
4121 : : * <bb 3> [local count: 434070867]:
4122 : : * _2 = x.0_1 + 255;
4123 : : * <bb 4> [local count: 1073741824]:
4124 : : * # _9 = PHI <_2(3), 128(2)>
4125 : : * _4 = (int8_t) _9;
4126 : : * =>
4127 : : * _4 = .SAT_ADD (x_5, -1); */
4128 : :
4129 : : static void
4130 : 4781335 : match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
4131 : : {
4132 : 4781335 : tree ops[2];
4133 : 4781335 : tree lhs = gimple_assign_lhs (stmt);
4134 : :
4135 : 4781335 : if (gimple_unsigned_integer_sat_add (lhs, ops, NULL)
4136 : 4781335 : || gimple_signed_integer_sat_add (lhs, ops, NULL))
4137 : 34 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_ADD, lhs,
4138 : : ops[0], ops[1]);
4139 : 4781335 : }
4140 : :
4141 : : /*
4142 : : * Try to match saturation add with PHI.
4143 : : * For unsigned integer:
4144 : : * <bb 2> :
4145 : : * _1 = x_3(D) + y_4(D);
4146 : : * if (_1 >= x_3(D))
4147 : : * goto <bb 3>; [INV]
4148 : : * else
4149 : : * goto <bb 4>; [INV]
4150 : : *
4151 : : * <bb 3> :
4152 : : *
4153 : : * <bb 4> :
4154 : : * # _2 = PHI <255(2), _1(3)>
4155 : : * =>
4156 : : * <bb 4> [local count: 1073741824]:
4157 : : * _2 = .SAT_ADD (x_4(D), y_5(D));
4158 : : *
4159 : : * For signed integer:
4160 : : * x.0_1 = (long unsigned int) x_7(D);
4161 : : * y.1_2 = (long unsigned int) y_8(D);
4162 : : * _3 = x.0_1 + y.1_2;
4163 : : * sum_9 = (int64_t) _3;
4164 : : * _4 = x_7(D) ^ y_8(D);
4165 : : * _5 = x_7(D) ^ sum_9;
4166 : : * _15 = ~_4;
4167 : : * _16 = _5 & _15;
4168 : : * if (_16 < 0)
4169 : : * goto <bb 3>; [41.00%]
4170 : : * else
4171 : : * goto <bb 4>; [59.00%]
4172 : : * _11 = x_7(D) < 0;
4173 : : * _12 = (long int) _11;
4174 : : * _13 = -_12;
4175 : : * _14 = _13 ^ 9223372036854775807;
4176 : : * # _6 = PHI <_14(3), sum_9(2)>
4177 : : * =>
4178 : : * _6 = .SAT_ADD (x_5(D), y_6(D)); [tail call] */
4179 : :
4180 : : static bool
4181 : 4441152 : match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
4182 : : {
4183 : 4441152 : if (gimple_phi_num_args (phi) != 2)
4184 : : return false;
4185 : :
4186 : 3645526 : tree ops[2];
4187 : 3645526 : tree phi_result = gimple_phi_result (phi);
4188 : :
4189 : 3645526 : if (!gimple_unsigned_integer_sat_add (phi_result, ops, NULL)
4190 : 3645526 : && !gimple_signed_integer_sat_add (phi_result, ops, NULL))
4191 : : return false;
4192 : :
4193 : 21 : if (!TYPE_UNSIGNED (TREE_TYPE (ops[0])) && TREE_CODE (ops[1]) == INTEGER_CST)
4194 : 0 : ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
4195 : :
4196 : 21 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_ADD,
4197 : : phi_result, ops[0],
4198 : 21 : ops[1]);
4199 : : }
4200 : :
4201 : : /*
4202 : : * Try to match saturation unsigned sub.
4203 : : * _1 = _4 >= _5;
4204 : : * _3 = _4 - _5;
4205 : : * _6 = _1 ? _3 : 0;
4206 : : * =>
4207 : : * _6 = .SAT_SUB (_4, _5); */
4208 : :
4209 : : static void
4210 : 3267011 : match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
4211 : : {
4212 : 3267011 : tree ops[2];
4213 : 3267011 : tree lhs = gimple_assign_lhs (stmt);
4214 : :
4215 : 3267011 : if (gimple_unsigned_integer_sat_sub (lhs, ops, NULL))
4216 : 116 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_SUB, lhs,
4217 : : ops[0], ops[1]);
4218 : 3267011 : }
4219 : :
4220 : : /*
4221 : : * Try to match saturation unsigned mul.
4222 : : * _1 = (unsigned int) a_6(D);
4223 : : * _2 = (unsigned int) b_7(D);
4224 : : * x_8 = _1 * _2;
4225 : : * overflow_9 = x_8 > 255;
4226 : : * _3 = (unsigned char) overflow_9;
4227 : : * _4 = -_3;
4228 : : * _5 = (unsigned char) x_8;
4229 : : * _10 = _4 | _5;
4230 : : * =>
4231 : : * _10 = .SAT_SUB (a_6, b_7); */
4232 : :
4233 : : static void
4234 : 2372553 : match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt)
4235 : : {
4236 : 2372553 : tree ops[2];
4237 : 2372553 : tree lhs = gimple_assign_lhs (stmt);
4238 : :
4239 : 2372553 : if (gimple_unsigned_integer_sat_mul (lhs, ops, NULL))
4240 : 0 : build_saturation_binary_arith_call_and_replace (gsi, IFN_SAT_MUL, lhs,
4241 : : ops[0], ops[1]);
4242 : 2372553 : }
4243 : :
4244 : : /*
4245 : : * Try to match saturation unsigned sub.
4246 : : * <bb 2> [local count: 1073741824]:
4247 : : * if (x_2(D) > y_3(D))
4248 : : * goto <bb 3>; [50.00%]
4249 : : * else
4250 : : * goto <bb 4>; [50.00%]
4251 : : *
4252 : : * <bb 3> [local count: 536870912]:
4253 : : * _4 = x_2(D) - y_3(D);
4254 : : *
4255 : : * <bb 4> [local count: 1073741824]:
4256 : : * # _1 = PHI <0(2), _4(3)>
4257 : : * =>
4258 : : * <bb 4> [local count: 1073741824]:
4259 : : * _1 = .SAT_SUB (x_2(D), y_3(D)); */
4260 : : static bool
4261 : 4441135 : match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
4262 : : {
4263 : 4441135 : if (gimple_phi_num_args (phi) != 2)
4264 : : return false;
4265 : :
4266 : 3645509 : tree ops[2];
4267 : 3645509 : tree phi_result = gimple_phi_result (phi);
4268 : :
4269 : 3645509 : if (!gimple_unsigned_integer_sat_sub (phi_result, ops, NULL)
4270 : 3645509 : && !gimple_signed_integer_sat_sub (phi_result, ops, NULL))
4271 : : return false;
4272 : :
4273 : 14 : return build_saturation_binary_arith_call_and_insert (gsi, IFN_SAT_SUB,
4274 : : phi_result, ops[0],
4275 : 14 : ops[1]);
4276 : : }
4277 : :
4278 : : /*
4279 : : * Try to match saturation unsigned sub.
4280 : : * uint16_t x_4(D);
4281 : : * uint8_t _6;
4282 : : * overflow_5 = x_4(D) > 255;
4283 : : * _1 = (unsigned char) x_4(D);
4284 : : * _2 = (unsigned char) overflow_5;
4285 : : * _3 = -_2;
4286 : : * _6 = _1 | _3;
4287 : : * =>
4288 : : * _6 = .SAT_TRUNC (x_4(D));
4289 : : * */
4290 : : static void
4291 : 2563648 : match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
4292 : : {
4293 : 2563648 : tree ops[1];
4294 : 2563648 : tree lhs = gimple_assign_lhs (stmt);
4295 : 2563648 : tree type = TREE_TYPE (lhs);
4296 : :
4297 : 2563648 : if (gimple_unsigned_integer_sat_trunc (lhs, ops, NULL)
4298 : 2563748 : && direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4299 : 100 : tree_pair (type, TREE_TYPE (ops[0])),
4300 : : OPTIMIZE_FOR_BOTH))
4301 : : {
4302 : 73 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4303 : 73 : gimple_call_set_lhs (call, lhs);
4304 : 73 : gsi_replace (gsi, call, /* update_eh_info */ true);
4305 : : }
4306 : 2563648 : }
4307 : :
4308 : : /*
4309 : : * Try to match saturation truncate.
4310 : : * Aka:
4311 : : * x.0_1 = (unsigned long) x_4(D);
4312 : : * _2 = x.0_1 + 2147483648;
4313 : : * if (_2 > 4294967295)
4314 : : * goto <bb 4>; [50.00%]
4315 : : * else
4316 : : * goto <bb 3>; [50.00%]
4317 : : * ;; succ: 4
4318 : : * ;; 3
4319 : : *
4320 : : * ;; basic block 3, loop depth 0
4321 : : * ;; pred: 2
4322 : : * trunc_5 = (int32_t) x_4(D);
4323 : : * goto <bb 5>; [100.00%]
4324 : : * ;; succ: 5
4325 : : *
4326 : : * ;; basic block 4, loop depth 0
4327 : : * ;; pred: 2
4328 : : * _7 = x_4(D) < 0;
4329 : : * _8 = (int) _7;
4330 : : * _9 = -_8;
4331 : : * _10 = _9 ^ 2147483647;
4332 : : * ;; succ: 5
4333 : : *
4334 : : * ;; basic block 5, loop depth 0
4335 : : * ;; pred: 3
4336 : : * ;; 4
4337 : : * # _3 = PHI <trunc_5(3), _10(4)>
4338 : : * =>
4339 : : * _6 = .SAT_TRUNC (x_4(D));
4340 : : */
4341 : :
4342 : : static bool
4343 : 4441125 : match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
4344 : : {
4345 : 4441125 : if (gimple_phi_num_args (phi) != 2)
4346 : : return false;
4347 : :
4348 : 3645499 : tree ops[1];
4349 : 3645499 : tree phi_result = gimple_phi_result (phi);
4350 : 3645499 : tree type = TREE_TYPE (phi_result);
4351 : :
4352 : 3645499 : if (!gimple_unsigned_integer_sat_trunc (phi_result, ops, NULL)
4353 : 3645499 : && !gimple_signed_integer_sat_trunc (phi_result, ops, NULL))
4354 : : return false;
4355 : :
4356 : 0 : if (!direct_internal_fn_supported_p (IFN_SAT_TRUNC,
4357 : 0 : tree_pair (type, TREE_TYPE (ops[0])),
4358 : : OPTIMIZE_FOR_BOTH))
4359 : : return false;
4360 : :
4361 : 0 : gcall *call = gimple_build_call_internal (IFN_SAT_TRUNC, 1, ops[0]);
4362 : 0 : gimple_call_set_lhs (call, phi_result);
4363 : 0 : gsi_insert_before (gsi, call, GSI_SAME_STMT);
4364 : :
4365 : 0 : return true;
4366 : : }
4367 : :
4368 : : /* Recognize for unsigned x
4369 : : x = y - z;
4370 : : if (x > y)
4371 : : where there are other uses of x and replace it with
4372 : : _7 = .SUB_OVERFLOW (y, z);
4373 : : x = REALPART_EXPR <_7>;
4374 : : _8 = IMAGPART_EXPR <_7>;
4375 : : if (_8)
4376 : : and similarly for addition.
4377 : :
4378 : : Also recognize:
4379 : : yc = (type) y;
4380 : : zc = (type) z;
4381 : : x = yc + zc;
4382 : : if (x > max)
4383 : : where y and z have unsigned types with maximum max
4384 : : and there are other uses of x and all of those cast x
4385 : : back to that unsigned type and again replace it with
4386 : : _7 = .ADD_OVERFLOW (y, z);
4387 : : _9 = REALPART_EXPR <_7>;
4388 : : _8 = IMAGPART_EXPR <_7>;
4389 : : if (_8)
4390 : : and replace (utype) x with _9.
4391 : : Or with x >> popcount (max) instead of x > max.
4392 : :
4393 : : Also recognize:
4394 : : x = ~z;
4395 : : if (y > x)
4396 : : and replace it with
4397 : : _7 = .ADD_OVERFLOW (y, z);
4398 : : _8 = IMAGPART_EXPR <_7>;
4399 : : if (_8)
4400 : :
4401 : : And also recognize:
4402 : : z = x * y;
4403 : : if (x != 0)
4404 : : goto <bb 3>; [50.00%]
4405 : : else
4406 : : goto <bb 4>; [50.00%]
4407 : :
4408 : : <bb 3> [local count: 536870913]:
4409 : : _2 = z / x;
4410 : : _9 = _2 != y;
4411 : : _10 = (int) _9;
4412 : :
4413 : : <bb 4> [local count: 1073741824]:
4414 : : # iftmp.0_3 = PHI <_10(3), 0(2)>
4415 : : and replace it with
4416 : : _7 = .MUL_OVERFLOW (x, y);
4417 : : z = IMAGPART_EXPR <_7>;
4418 : : _8 = IMAGPART_EXPR <_7>;
4419 : : _9 = _8 != 0;
4420 : : iftmp.0_3 = (int) _9; */
4421 : :
4422 : : static bool
4423 : 3237260 : match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt,
4424 : : enum tree_code code, bool *cfg_changed)
4425 : : {
4426 : 3237260 : tree lhs = gimple_assign_lhs (stmt);
4427 : 3237260 : tree type = TREE_TYPE (lhs);
4428 : 3237260 : use_operand_p use_p;
4429 : 3237260 : imm_use_iterator iter;
4430 : 3237260 : bool use_seen = false;
4431 : 3237260 : bool ovf_use_seen = false;
4432 : 3237260 : gimple *use_stmt;
4433 : 3237260 : gimple *add_stmt = NULL;
4434 : 3237260 : bool add_first = false;
4435 : 3237260 : gimple *cond_stmt = NULL;
4436 : 3237260 : gimple *cast_stmt = NULL;
4437 : 3237260 : tree cast_lhs = NULL_TREE;
4438 : :
4439 : 3237260 : gcc_checking_assert (code == PLUS_EXPR
4440 : : || code == MINUS_EXPR
4441 : : || code == MULT_EXPR
4442 : : || code == BIT_NOT_EXPR);
4443 : 3237260 : if (!INTEGRAL_TYPE_P (type)
4444 : 2720323 : || !TYPE_UNSIGNED (type)
4445 : 1880426 : || has_zero_uses (lhs)
4446 : 3237260 : || (code != PLUS_EXPR
4447 : 1880140 : && code != MULT_EXPR
4448 : 176580 : && optab_handler (code == MINUS_EXPR ? usubv4_optab : uaddv4_optab,
4449 : 152159 : TYPE_MODE (type)) == CODE_FOR_nothing))
4450 : 1359210 : return false;
4451 : :
4452 : 1878050 : tree rhs1 = gimple_assign_rhs1 (stmt);
4453 : 1878050 : tree rhs2 = gimple_assign_rhs2 (stmt);
4454 : 5088437 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4455 : : {
4456 : 3216675 : use_stmt = USE_STMT (use_p);
4457 : 3216675 : if (is_gimple_debug (use_stmt))
4458 : 456256 : continue;
4459 : :
4460 : 2760419 : tree other = NULL_TREE;
4461 : 2760419 : if (arith_overflow_check_p (stmt, NULL, use_stmt, NULL_TREE, &other))
4462 : : {
4463 : 6780 : if (code == BIT_NOT_EXPR)
4464 : : {
4465 : 187 : gcc_assert (other);
4466 : 187 : if (TREE_CODE (other) != SSA_NAME)
4467 : 0 : return false;
4468 : 187 : if (rhs2 == NULL)
4469 : 187 : rhs2 = other;
4470 : : else
4471 : : return false;
4472 : 187 : cond_stmt = use_stmt;
4473 : : }
4474 : : ovf_use_seen = true;
4475 : : }
4476 : : else
4477 : : {
4478 : 2753639 : use_seen = true;
4479 : 2753639 : if (code == MULT_EXPR
4480 : 2753639 : && cast_stmt == NULL
4481 : 2753639 : && gimple_assign_cast_p (use_stmt))
4482 : : {
4483 : 30979 : cast_lhs = gimple_assign_lhs (use_stmt);
4484 : 61958 : if (INTEGRAL_TYPE_P (TREE_TYPE (cast_lhs))
4485 : 30430 : && !TYPE_UNSIGNED (TREE_TYPE (cast_lhs))
4486 : 58361 : && (TYPE_PRECISION (TREE_TYPE (cast_lhs))
4487 : 27382 : == TYPE_PRECISION (TREE_TYPE (lhs))))
4488 : : cast_stmt = use_stmt;
4489 : : else
4490 : : cast_lhs = NULL_TREE;
4491 : : }
4492 : : }
4493 : 2760419 : if (ovf_use_seen && use_seen)
4494 : : break;
4495 : : }
4496 : :
4497 : 1878050 : if (!ovf_use_seen
4498 : 1878050 : && code == MULT_EXPR
4499 : 430576 : && cast_stmt)
4500 : : {
4501 : 26931 : if (TREE_CODE (rhs1) != SSA_NAME
4502 : 26931 : || (TREE_CODE (rhs2) != SSA_NAME && TREE_CODE (rhs2) != INTEGER_CST))
4503 : : return false;
4504 : 61411 : FOR_EACH_IMM_USE_FAST (use_p, iter, cast_lhs)
4505 : : {
4506 : 34480 : use_stmt = USE_STMT (use_p);
4507 : 34480 : if (is_gimple_debug (use_stmt))
4508 : 1181 : continue;
4509 : :
4510 : 33299 : if (arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4511 : : NULL_TREE, NULL))
4512 : 34480 : ovf_use_seen = true;
4513 : : }
4514 : : }
4515 : : else
4516 : : {
4517 : : cast_stmt = NULL;
4518 : : cast_lhs = NULL_TREE;
4519 : : }
4520 : :
4521 : 1878050 : tree maxval = NULL_TREE;
4522 : 1878050 : if (!ovf_use_seen
4523 : 13563 : || (code != MULT_EXPR && (code == BIT_NOT_EXPR ? use_seen : !use_seen))
4524 : 6406 : || (code == PLUS_EXPR
4525 : 6136 : && optab_handler (uaddv4_optab,
4526 : 6136 : TYPE_MODE (type)) == CODE_FOR_nothing)
4527 : 1891311 : || (code == MULT_EXPR
4528 : 219 : && optab_handler (cast_stmt ? mulv4_optab : umulv4_optab,
4529 : 147 : TYPE_MODE (type)) == CODE_FOR_nothing
4530 : 3 : && (use_seen
4531 : 3 : || cast_stmt
4532 : 0 : || !can_mult_highpart_p (TYPE_MODE (type), true))))
4533 : : {
4534 : 1871500 : if (code != PLUS_EXPR)
4535 : : return false;
4536 : 1291197 : if (TREE_CODE (rhs1) != SSA_NAME
4537 : 1291197 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs1)))
4538 : : return false;
4539 : 313455 : rhs1 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs1));
4540 : 313455 : tree type1 = TREE_TYPE (rhs1);
4541 : 313455 : if (!INTEGRAL_TYPE_P (type1)
4542 : 167536 : || !TYPE_UNSIGNED (type1)
4543 : 38708 : || TYPE_PRECISION (type1) >= TYPE_PRECISION (type)
4544 : 329742 : || (TYPE_PRECISION (type1)
4545 : 32574 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type1))))
4546 : 302919 : return false;
4547 : 10536 : if (TREE_CODE (rhs2) == INTEGER_CST)
4548 : : {
4549 : 3809 : if (wi::ne_p (wi::rshift (wi::to_wide (rhs2),
4550 : 3809 : TYPE_PRECISION (type1),
4551 : 7618 : UNSIGNED), 0))
4552 : : return false;
4553 : 1183 : rhs2 = fold_convert (type1, rhs2);
4554 : : }
4555 : : else
4556 : : {
4557 : 6727 : if (TREE_CODE (rhs2) != SSA_NAME
4558 : 6727 : || !gimple_assign_cast_p (SSA_NAME_DEF_STMT (rhs2)))
4559 : : return false;
4560 : 2324 : rhs2 = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (rhs2));
4561 : 2324 : tree type2 = TREE_TYPE (rhs2);
4562 : 2324 : if (!INTEGRAL_TYPE_P (type2)
4563 : 1098 : || !TYPE_UNSIGNED (type2)
4564 : 395 : || TYPE_PRECISION (type2) >= TYPE_PRECISION (type)
4565 : 2675 : || (TYPE_PRECISION (type2)
4566 : 702 : != GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (type2))))
4567 : 1986 : return false;
4568 : : }
4569 : 1521 : if (TYPE_PRECISION (type1) >= TYPE_PRECISION (TREE_TYPE (rhs2)))
4570 : : type = type1;
4571 : : else
4572 : 5 : type = TREE_TYPE (rhs2);
4573 : :
4574 : 1521 : if (TREE_CODE (type) != INTEGER_TYPE
4575 : 3040 : || optab_handler (uaddv4_optab,
4576 : 1519 : TYPE_MODE (type)) == CODE_FOR_nothing)
4577 : 2 : return false;
4578 : :
4579 : 1519 : maxval = wide_int_to_tree (type, wi::max_value (TYPE_PRECISION (type),
4580 : : UNSIGNED));
4581 : 1519 : ovf_use_seen = false;
4582 : 1519 : use_seen = false;
4583 : 1519 : basic_block use_bb = NULL;
4584 : 1555 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
4585 : : {
4586 : 1531 : use_stmt = USE_STMT (use_p);
4587 : 1531 : if (is_gimple_debug (use_stmt))
4588 : 8 : continue;
4589 : :
4590 : 1523 : if (arith_overflow_check_p (stmt, NULL, use_stmt, maxval, NULL))
4591 : : {
4592 : 12 : ovf_use_seen = true;
4593 : 12 : use_bb = gimple_bb (use_stmt);
4594 : : }
4595 : : else
4596 : : {
4597 : 1511 : if (!gimple_assign_cast_p (use_stmt)
4598 : 1511 : || gimple_assign_rhs_code (use_stmt) == VIEW_CONVERT_EXPR)
4599 : : return false;
4600 : 70 : tree use_lhs = gimple_assign_lhs (use_stmt);
4601 : 140 : if (!INTEGRAL_TYPE_P (TREE_TYPE (use_lhs))
4602 : 140 : || (TYPE_PRECISION (TREE_TYPE (use_lhs))
4603 : 70 : > TYPE_PRECISION (type)))
4604 : : return false;
4605 : : use_seen = true;
4606 : : }
4607 : : }
4608 : 24 : if (!ovf_use_seen)
4609 : : return false;
4610 : 12 : if (!useless_type_conversion_p (type, TREE_TYPE (rhs1)))
4611 : : {
4612 : 2 : if (!use_seen)
4613 : : return false;
4614 : 2 : tree new_rhs1 = make_ssa_name (type);
4615 : 2 : gimple *g = gimple_build_assign (new_rhs1, NOP_EXPR, rhs1);
4616 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4617 : 2 : rhs1 = new_rhs1;
4618 : : }
4619 : 10 : else if (!useless_type_conversion_p (type, TREE_TYPE (rhs2)))
4620 : : {
4621 : 2 : if (!use_seen)
4622 : : return false;
4623 : 2 : tree new_rhs2 = make_ssa_name (type);
4624 : 2 : gimple *g = gimple_build_assign (new_rhs2, NOP_EXPR, rhs2);
4625 : 2 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4626 : 2 : rhs2 = new_rhs2;
4627 : : }
4628 : 8 : else if (!use_seen)
4629 : : {
4630 : : /* If there are no uses of the wider addition, check if
4631 : : forwprop has not created a narrower addition.
4632 : : Require it to be in the same bb as the overflow check. */
4633 : 10 : FOR_EACH_IMM_USE_FAST (use_p, iter, rhs1)
4634 : : {
4635 : 10 : use_stmt = USE_STMT (use_p);
4636 : 10 : if (is_gimple_debug (use_stmt))
4637 : 0 : continue;
4638 : :
4639 : 10 : if (use_stmt == stmt)
4640 : 0 : continue;
4641 : :
4642 : 10 : if (!is_gimple_assign (use_stmt)
4643 : 10 : || gimple_bb (use_stmt) != use_bb
4644 : 20 : || gimple_assign_rhs_code (use_stmt) != PLUS_EXPR)
4645 : 2 : continue;
4646 : :
4647 : 8 : if (gimple_assign_rhs1 (use_stmt) == rhs1)
4648 : : {
4649 : 8 : if (!operand_equal_p (gimple_assign_rhs2 (use_stmt),
4650 : : rhs2, 0))
4651 : 0 : continue;
4652 : : }
4653 : 0 : else if (gimple_assign_rhs2 (use_stmt) == rhs1)
4654 : : {
4655 : 0 : if (gimple_assign_rhs1 (use_stmt) != rhs2)
4656 : 0 : continue;
4657 : : }
4658 : : else
4659 : 0 : continue;
4660 : :
4661 : 8 : add_stmt = use_stmt;
4662 : 8 : break;
4663 : : }
4664 : 8 : if (add_stmt == NULL)
4665 : : return false;
4666 : :
4667 : : /* If stmt and add_stmt are in the same bb, we need to find out
4668 : : which one is earlier. If they are in different bbs, we've
4669 : : checked add_stmt is in the same bb as one of the uses of the
4670 : : stmt lhs, so stmt needs to dominate add_stmt too. */
4671 : 8 : if (gimple_bb (stmt) == gimple_bb (add_stmt))
4672 : : {
4673 : 8 : gimple_stmt_iterator gsif = *gsi;
4674 : 8 : gimple_stmt_iterator gsib = *gsi;
4675 : 8 : int i;
4676 : : /* Search both forward and backward from stmt and have a small
4677 : : upper bound. */
4678 : 20 : for (i = 0; i < 128; i++)
4679 : : {
4680 : 20 : if (!gsi_end_p (gsib))
4681 : : {
4682 : 18 : gsi_prev_nondebug (&gsib);
4683 : 18 : if (gsi_stmt (gsib) == add_stmt)
4684 : : {
4685 : : add_first = true;
4686 : : break;
4687 : : }
4688 : : }
4689 : 2 : else if (gsi_end_p (gsif))
4690 : : break;
4691 : 18 : if (!gsi_end_p (gsif))
4692 : : {
4693 : 18 : gsi_next_nondebug (&gsif);
4694 : 18 : if (gsi_stmt (gsif) == add_stmt)
4695 : : break;
4696 : : }
4697 : : }
4698 : 8 : if (i == 128)
4699 : 0 : return false;
4700 : 8 : if (add_first)
4701 : 2 : *gsi = gsi_for_stmt (add_stmt);
4702 : : }
4703 : : }
4704 : : }
4705 : :
4706 : 6562 : if (code == BIT_NOT_EXPR)
4707 : 170 : *gsi = gsi_for_stmt (cond_stmt);
4708 : :
4709 : 6562 : auto_vec<gimple *, 8> mul_stmts;
4710 : 6562 : if (code == MULT_EXPR && cast_stmt)
4711 : : {
4712 : 75 : type = TREE_TYPE (cast_lhs);
4713 : 75 : gimple *g = SSA_NAME_DEF_STMT (rhs1);
4714 : 75 : if (gimple_assign_cast_p (g)
4715 : 38 : && useless_type_conversion_p (type,
4716 : 38 : TREE_TYPE (gimple_assign_rhs1 (g)))
4717 : 113 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4718 : : rhs1 = gimple_assign_rhs1 (g);
4719 : : else
4720 : : {
4721 : 37 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs1);
4722 : 37 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4723 : 37 : rhs1 = gimple_assign_lhs (g);
4724 : 37 : mul_stmts.quick_push (g);
4725 : : }
4726 : 75 : if (TREE_CODE (rhs2) == INTEGER_CST)
4727 : 32 : rhs2 = fold_convert (type, rhs2);
4728 : : else
4729 : : {
4730 : 43 : g = SSA_NAME_DEF_STMT (rhs2);
4731 : 43 : if (gimple_assign_cast_p (g)
4732 : 22 : && useless_type_conversion_p (type,
4733 : 22 : TREE_TYPE (gimple_assign_rhs1 (g)))
4734 : 65 : && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (gimple_assign_rhs1 (g)))
4735 : : rhs2 = gimple_assign_rhs1 (g);
4736 : : else
4737 : : {
4738 : 21 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, rhs2);
4739 : 21 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4740 : 21 : rhs2 = gimple_assign_lhs (g);
4741 : 21 : mul_stmts.quick_push (g);
4742 : : }
4743 : : }
4744 : : }
4745 : 6562 : tree ctype = build_complex_type (type);
4746 : 12980 : gcall *g = gimple_build_call_internal (code == MULT_EXPR
4747 : : ? IFN_MUL_OVERFLOW
4748 : : : code != MINUS_EXPR
4749 : 6418 : ? IFN_ADD_OVERFLOW : IFN_SUB_OVERFLOW,
4750 : : 2, rhs1, rhs2);
4751 : 6562 : tree ctmp = make_ssa_name (ctype);
4752 : 6562 : gimple_call_set_lhs (g, ctmp);
4753 : 6562 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
4754 : 6562 : tree new_lhs = (maxval || cast_stmt) ? make_ssa_name (type) : lhs;
4755 : 6562 : gassign *g2;
4756 : 6562 : if (code != BIT_NOT_EXPR)
4757 : : {
4758 : 6392 : g2 = gimple_build_assign (new_lhs, REALPART_EXPR,
4759 : : build1 (REALPART_EXPR, type, ctmp));
4760 : 6392 : if (maxval || cast_stmt)
4761 : : {
4762 : 87 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4763 : 87 : if (add_first)
4764 : 2 : *gsi = gsi_for_stmt (stmt);
4765 : : }
4766 : : else
4767 : 6305 : gsi_replace (gsi, g2, true);
4768 : 6392 : if (code == MULT_EXPR)
4769 : : {
4770 : 144 : mul_stmts.quick_push (g);
4771 : 144 : mul_stmts.quick_push (g2);
4772 : 144 : if (cast_stmt)
4773 : : {
4774 : 75 : g2 = gimple_build_assign (lhs, NOP_EXPR, new_lhs);
4775 : 75 : gsi_replace (gsi, g2, true);
4776 : 75 : mul_stmts.quick_push (g2);
4777 : : }
4778 : : }
4779 : : }
4780 : 6562 : tree ovf = make_ssa_name (type);
4781 : 6562 : g2 = gimple_build_assign (ovf, IMAGPART_EXPR,
4782 : : build1 (IMAGPART_EXPR, type, ctmp));
4783 : 6562 : if (code != BIT_NOT_EXPR)
4784 : 6392 : gsi_insert_after (gsi, g2, GSI_NEW_STMT);
4785 : : else
4786 : 170 : gsi_insert_before (gsi, g2, GSI_SAME_STMT);
4787 : 6562 : if (code == MULT_EXPR)
4788 : 144 : mul_stmts.quick_push (g2);
4789 : :
4790 : 34079 : FOR_EACH_IMM_USE_STMT (use_stmt, iter, cast_lhs ? cast_lhs : lhs)
4791 : : {
4792 : 21030 : if (is_gimple_debug (use_stmt))
4793 : 4846 : continue;
4794 : :
4795 : 16184 : gimple *orig_use_stmt = use_stmt;
4796 : 16184 : int ovf_use = arith_overflow_check_p (stmt, cast_stmt, use_stmt,
4797 : : maxval, NULL);
4798 : 16184 : if (ovf_use == 0)
4799 : : {
4800 : 9592 : gcc_assert (code != BIT_NOT_EXPR);
4801 : 9592 : if (maxval)
4802 : : {
4803 : 4 : tree use_lhs = gimple_assign_lhs (use_stmt);
4804 : 4 : gimple_assign_set_rhs1 (use_stmt, new_lhs);
4805 : 4 : if (useless_type_conversion_p (TREE_TYPE (use_lhs),
4806 : 4 : TREE_TYPE (new_lhs)))
4807 : 4 : gimple_assign_set_rhs_code (use_stmt, SSA_NAME);
4808 : 4 : update_stmt (use_stmt);
4809 : : }
4810 : 9592 : continue;
4811 : 9592 : }
4812 : 6592 : if (gimple_code (use_stmt) == GIMPLE_COND)
4813 : : {
4814 : 4287 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4815 : 4287 : gimple_cond_set_lhs (cond_stmt, ovf);
4816 : 4287 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4817 : 4439 : gimple_cond_set_code (cond_stmt, ovf_use == 1 ? NE_EXPR : EQ_EXPR);
4818 : : }
4819 : : else
4820 : : {
4821 : 2305 : gcc_checking_assert (is_gimple_assign (use_stmt));
4822 : 2305 : if (gimple_assign_rhs_class (use_stmt) == GIMPLE_BINARY_RHS)
4823 : : {
4824 : 2305 : if (gimple_assign_rhs_code (use_stmt) == RSHIFT_EXPR)
4825 : : {
4826 : 6 : g2 = gimple_build_assign (make_ssa_name (boolean_type_node),
4827 : : ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4828 : : ovf, build_int_cst (type, 0));
4829 : 6 : gimple_stmt_iterator gsiu = gsi_for_stmt (use_stmt);
4830 : 6 : gsi_insert_before (&gsiu, g2, GSI_SAME_STMT);
4831 : 6 : gimple_assign_set_rhs_with_ops (&gsiu, NOP_EXPR,
4832 : : gimple_assign_lhs (g2));
4833 : 6 : update_stmt (use_stmt);
4834 : 6 : use_operand_p use;
4835 : 6 : single_imm_use (gimple_assign_lhs (use_stmt), &use,
4836 : : &use_stmt);
4837 : 6 : if (gimple_code (use_stmt) == GIMPLE_COND)
4838 : : {
4839 : 0 : gcond *cond_stmt = as_a <gcond *> (use_stmt);
4840 : 0 : gimple_cond_set_lhs (cond_stmt, ovf);
4841 : 0 : gimple_cond_set_rhs (cond_stmt, build_int_cst (type, 0));
4842 : : }
4843 : : else
4844 : : {
4845 : 6 : gcc_checking_assert (is_gimple_assign (use_stmt));
4846 : 6 : if (gimple_assign_rhs_class (use_stmt)
4847 : : == GIMPLE_BINARY_RHS)
4848 : : {
4849 : 0 : gimple_assign_set_rhs1 (use_stmt, ovf);
4850 : 0 : gimple_assign_set_rhs2 (use_stmt,
4851 : : build_int_cst (type, 0));
4852 : : }
4853 : 6 : else if (gimple_assign_cast_p (use_stmt))
4854 : 6 : gimple_assign_set_rhs1 (use_stmt, ovf);
4855 : : else
4856 : : {
4857 : 0 : tree_code sc = gimple_assign_rhs_code (use_stmt);
4858 : 0 : gcc_checking_assert (sc == COND_EXPR);
4859 : 0 : tree cond = gimple_assign_rhs1 (use_stmt);
4860 : 0 : cond = build2 (TREE_CODE (cond),
4861 : : boolean_type_node, ovf,
4862 : : build_int_cst (type, 0));
4863 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4864 : : }
4865 : : }
4866 : 6 : update_stmt (use_stmt);
4867 : 6 : gsi_remove (&gsiu, true);
4868 : 6 : gsiu = gsi_for_stmt (g2);
4869 : 6 : gsi_remove (&gsiu, true);
4870 : 6 : continue;
4871 : 6 : }
4872 : : else
4873 : : {
4874 : 2299 : gimple_assign_set_rhs1 (use_stmt, ovf);
4875 : 2299 : gimple_assign_set_rhs2 (use_stmt, build_int_cst (type, 0));
4876 : 2448 : gimple_assign_set_rhs_code (use_stmt,
4877 : : ovf_use == 1
4878 : : ? NE_EXPR : EQ_EXPR);
4879 : : }
4880 : : }
4881 : : else
4882 : : {
4883 : 0 : gcc_checking_assert (gimple_assign_rhs_code (use_stmt)
4884 : : == COND_EXPR);
4885 : 0 : tree cond = build2 (ovf_use == 1 ? NE_EXPR : EQ_EXPR,
4886 : : boolean_type_node, ovf,
4887 : : build_int_cst (type, 0));
4888 : 0 : gimple_assign_set_rhs1 (use_stmt, cond);
4889 : : }
4890 : : }
4891 : 6586 : update_stmt (use_stmt);
4892 : 6586 : if (code == MULT_EXPR && use_stmt != orig_use_stmt)
4893 : : {
4894 : 144 : gimple_stmt_iterator gsi2 = gsi_for_stmt (orig_use_stmt);
4895 : 144 : maybe_optimize_guarding_check (mul_stmts, use_stmt, orig_use_stmt,
4896 : : cfg_changed);
4897 : 144 : use_operand_p use;
4898 : 144 : gimple *cast_stmt;
4899 : 144 : if (single_imm_use (gimple_assign_lhs (orig_use_stmt), &use,
4900 : : &cast_stmt)
4901 : 144 : && gimple_assign_cast_p (cast_stmt))
4902 : : {
4903 : 2 : gimple_stmt_iterator gsi3 = gsi_for_stmt (cast_stmt);
4904 : 2 : gsi_remove (&gsi3, true);
4905 : 2 : release_ssa_name (gimple_assign_lhs (cast_stmt));
4906 : : }
4907 : 144 : gsi_remove (&gsi2, true);
4908 : 144 : release_ssa_name (gimple_assign_lhs (orig_use_stmt));
4909 : : }
4910 : 6562 : }
4911 : 6562 : if (maxval)
4912 : : {
4913 : 12 : gimple_stmt_iterator gsi2 = gsi_for_stmt (stmt);
4914 : 12 : gsi_remove (&gsi2, true);
4915 : 12 : if (add_stmt)
4916 : : {
4917 : 8 : gimple *g = gimple_build_assign (gimple_assign_lhs (add_stmt),
4918 : : new_lhs);
4919 : 8 : gsi2 = gsi_for_stmt (add_stmt);
4920 : 8 : gsi_replace (&gsi2, g, true);
4921 : : }
4922 : : }
4923 : 6550 : else if (code == BIT_NOT_EXPR)
4924 : : {
4925 : 170 : *gsi = gsi_for_stmt (stmt);
4926 : 170 : gsi_remove (gsi, true);
4927 : 170 : release_ssa_name (lhs);
4928 : 170 : return true;
4929 : : }
4930 : : return false;
4931 : 6562 : }
4932 : :
4933 : : /* Helper of match_uaddc_usubc. Look through an integral cast
4934 : : which should preserve [0, 1] range value (unless source has
4935 : : 1-bit signed type) and the cast has single use. */
4936 : :
4937 : : static gimple *
4938 : 1977908 : uaddc_cast (gimple *g)
4939 : : {
4940 : 1977908 : if (!gimple_assign_cast_p (g))
4941 : : return g;
4942 : 468244 : tree op = gimple_assign_rhs1 (g);
4943 : 468244 : if (TREE_CODE (op) == SSA_NAME
4944 : 393345 : && INTEGRAL_TYPE_P (TREE_TYPE (op))
4945 : 275270 : && (TYPE_PRECISION (TREE_TYPE (op)) > 1
4946 : 6269 : || TYPE_UNSIGNED (TREE_TYPE (op)))
4947 : 743514 : && has_single_use (gimple_assign_lhs (g)))
4948 : 175540 : return SSA_NAME_DEF_STMT (op);
4949 : : return g;
4950 : : }
4951 : :
4952 : : /* Helper of match_uaddc_usubc. Look through a NE_EXPR
4953 : : comparison with 0 which also preserves [0, 1] value range. */
4954 : :
4955 : : static gimple *
4956 : 1978067 : uaddc_ne0 (gimple *g)
4957 : : {
4958 : 1978067 : if (is_gimple_assign (g)
4959 : 1206172 : && gimple_assign_rhs_code (g) == NE_EXPR
4960 : 54851 : && integer_zerop (gimple_assign_rhs2 (g))
4961 : 5996 : && TREE_CODE (gimple_assign_rhs1 (g)) == SSA_NAME
4962 : 1984063 : && has_single_use (gimple_assign_lhs (g)))
4963 : 5681 : return SSA_NAME_DEF_STMT (gimple_assign_rhs1 (g));
4964 : : return g;
4965 : : }
4966 : :
4967 : : /* Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
4968 : : operand. */
4969 : :
4970 : : static bool
4971 : 1978898 : uaddc_is_cplxpart (gimple *g, tree_code part)
4972 : : {
4973 : 1978898 : return (is_gimple_assign (g)
4974 : 1205098 : && gimple_assign_rhs_code (g) == part
4975 : 1981303 : && TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (g), 0)) == SSA_NAME);
4976 : : }
4977 : :
4978 : : /* Try to match e.g.
4979 : : _29 = .ADD_OVERFLOW (_3, _4);
4980 : : _30 = REALPART_EXPR <_29>;
4981 : : _31 = IMAGPART_EXPR <_29>;
4982 : : _32 = .ADD_OVERFLOW (_30, _38);
4983 : : _33 = REALPART_EXPR <_32>;
4984 : : _34 = IMAGPART_EXPR <_32>;
4985 : : _35 = _31 + _34;
4986 : : as
4987 : : _36 = .UADDC (_3, _4, _38);
4988 : : _33 = REALPART_EXPR <_36>;
4989 : : _35 = IMAGPART_EXPR <_36>;
4990 : : or
4991 : : _22 = .SUB_OVERFLOW (_6, _5);
4992 : : _23 = REALPART_EXPR <_22>;
4993 : : _24 = IMAGPART_EXPR <_22>;
4994 : : _25 = .SUB_OVERFLOW (_23, _37);
4995 : : _26 = REALPART_EXPR <_25>;
4996 : : _27 = IMAGPART_EXPR <_25>;
4997 : : _28 = _24 | _27;
4998 : : as
4999 : : _29 = .USUBC (_6, _5, _37);
5000 : : _26 = REALPART_EXPR <_29>;
5001 : : _288 = IMAGPART_EXPR <_29>;
5002 : : provided _38 or _37 above have [0, 1] range
5003 : : and _3, _4 and _30 or _6, _5 and _23 are unsigned
5004 : : integral types with the same precision. Whether + or | or ^ is
5005 : : used on the IMAGPART_EXPR results doesn't matter, with one of
5006 : : added or subtracted operands in [0, 1] range at most one
5007 : : .ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow. */
5008 : :
5009 : : static bool
5010 : 2728431 : match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
5011 : : {
5012 : 2728431 : tree rhs[4];
5013 : 2728431 : rhs[0] = gimple_assign_rhs1 (stmt);
5014 : 2728431 : rhs[1] = gimple_assign_rhs2 (stmt);
5015 : 2728431 : rhs[2] = NULL_TREE;
5016 : 2728431 : rhs[3] = NULL_TREE;
5017 : 2728431 : tree type = TREE_TYPE (rhs[0]);
5018 : 2728431 : if (!INTEGRAL_TYPE_P (type) || !TYPE_UNSIGNED (type))
5019 : : return false;
5020 : :
5021 : 1589765 : auto_vec<gimple *, 2> temp_stmts;
5022 : 1589765 : if (code != BIT_IOR_EXPR && code != BIT_XOR_EXPR)
5023 : : {
5024 : : /* If overflow flag is ignored on the MSB limb, we can end up with
5025 : : the most significant limb handled as r = op1 + op2 + ovf1 + ovf2;
5026 : : or r = op1 - op2 - ovf1 - ovf2; or various equivalent expressions
5027 : : thereof. Handle those like the ovf = ovf1 + ovf2; case to recognize
5028 : : the limb below the MSB, but also create another .UADDC/.USUBC call
5029 : : for the last limb.
5030 : :
5031 : : First look through assignments with the same rhs code as CODE,
5032 : : with the exception that subtraction of a constant is canonicalized
5033 : : into addition of its negation. rhs[0] will be minuend for
5034 : : subtractions and one of addends for addition, all other assigned
5035 : : rhs[i] operands will be subtrahends or other addends. */
5036 : 1457536 : while (TREE_CODE (rhs[0]) == SSA_NAME && !rhs[3])
5037 : : {
5038 : 1433101 : gimple *g = SSA_NAME_DEF_STMT (rhs[0]);
5039 : 1433101 : if (has_single_use (rhs[0])
5040 : 484739 : && is_gimple_assign (g)
5041 : 1859853 : && (gimple_assign_rhs_code (g) == code
5042 : 400192 : || (code == MINUS_EXPR
5043 : 51952 : && gimple_assign_rhs_code (g) == PLUS_EXPR
5044 : 15898 : && TREE_CODE (gimple_assign_rhs2 (g)) == INTEGER_CST)))
5045 : : {
5046 : 38576 : tree r2 = gimple_assign_rhs2 (g);
5047 : 38576 : if (gimple_assign_rhs_code (g) != code)
5048 : : {
5049 : 12016 : r2 = const_unop (NEGATE_EXPR, TREE_TYPE (r2), r2);
5050 : 12016 : if (!r2)
5051 : : break;
5052 : : }
5053 : 38576 : rhs[0] = gimple_assign_rhs1 (g);
5054 : 38576 : tree &r = rhs[2] ? rhs[3] : rhs[2];
5055 : 38576 : r = r2;
5056 : 38576 : temp_stmts.quick_push (g);
5057 : : }
5058 : : else
5059 : : break;
5060 : : }
5061 : 4256880 : for (int i = 1; i <= 2; ++i)
5062 : 2883962 : while (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME && !rhs[3])
5063 : : {
5064 : 507765 : gimple *g = SSA_NAME_DEF_STMT (rhs[i]);
5065 : 507765 : if (has_single_use (rhs[i])
5066 : 264793 : && is_gimple_assign (g)
5067 : 756874 : && gimple_assign_rhs_code (g) == PLUS_EXPR)
5068 : : {
5069 : 46042 : rhs[i] = gimple_assign_rhs1 (g);
5070 : 46042 : if (rhs[2])
5071 : 9601 : rhs[3] = gimple_assign_rhs2 (g);
5072 : : else
5073 : 36441 : rhs[2] = gimple_assign_rhs2 (g);
5074 : 46042 : temp_stmts.quick_push (g);
5075 : : }
5076 : : else
5077 : : break;
5078 : : }
5079 : : /* If there are just 3 addends or one minuend and two subtrahends,
5080 : : check for UADDC or USUBC being pattern recognized earlier.
5081 : : Say r = op1 + op2 + ovf1 + ovf2; where the (ovf1 + ovf2) part
5082 : : got pattern matched earlier as __imag__ .UADDC (arg1, arg2, arg3)
5083 : : etc. */
5084 : 1418960 : if (rhs[2] && !rhs[3])
5085 : : {
5086 : 291387 : for (int i = (code == MINUS_EXPR ? 1 : 0); i < 3; ++i)
5087 : 169626 : if (TREE_CODE (rhs[i]) == SSA_NAME)
5088 : : {
5089 : 132225 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5090 : 132225 : im = uaddc_ne0 (im);
5091 : 132225 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5092 : : {
5093 : : /* We found one of the 3 addends or 2 subtrahends to be
5094 : : __imag__ of something, verify it is .UADDC/.USUBC. */
5095 : 215 : tree rhs1 = gimple_assign_rhs1 (im);
5096 : 215 : gimple *ovf = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs1, 0));
5097 : 215 : tree ovf_lhs = NULL_TREE;
5098 : 215 : tree ovf_arg1 = NULL_TREE, ovf_arg2 = NULL_TREE;
5099 : 235 : if (gimple_call_internal_p (ovf, code == PLUS_EXPR
5100 : : ? IFN_ADD_OVERFLOW
5101 : : : IFN_SUB_OVERFLOW))
5102 : : {
5103 : : /* Or verify it is .ADD_OVERFLOW/.SUB_OVERFLOW.
5104 : : This is for the case of 2 chained .UADDC/.USUBC,
5105 : : where the first one uses 0 carry-in and the second
5106 : : one ignores the carry-out.
5107 : : So, something like:
5108 : : _16 = .ADD_OVERFLOW (_1, _2);
5109 : : _17 = REALPART_EXPR <_16>;
5110 : : _18 = IMAGPART_EXPR <_16>;
5111 : : _15 = _3 + _4;
5112 : : _12 = _15 + _18;
5113 : : where the first 3 statements come from the lower
5114 : : limb addition and the last 2 from the higher limb
5115 : : which ignores carry-out. */
5116 : 197 : ovf_lhs = gimple_call_lhs (ovf);
5117 : 197 : tree ovf_lhs_type = TREE_TYPE (TREE_TYPE (ovf_lhs));
5118 : 197 : ovf_arg1 = gimple_call_arg (ovf, 0);
5119 : 197 : ovf_arg2 = gimple_call_arg (ovf, 1);
5120 : : /* In that case we need to punt if the types don't
5121 : : mismatch. */
5122 : 197 : if (!types_compatible_p (type, ovf_lhs_type)
5123 : 197 : || !types_compatible_p (type, TREE_TYPE (ovf_arg1))
5124 : 390 : || !types_compatible_p (type,
5125 : 193 : TREE_TYPE (ovf_arg2)))
5126 : : ovf_lhs = NULL_TREE;
5127 : : else
5128 : : {
5129 : 479 : for (int i = (code == PLUS_EXPR ? 1 : 0);
5130 : 479 : i >= 0; --i)
5131 : : {
5132 : 339 : tree r = gimple_call_arg (ovf, i);
5133 : 339 : if (TREE_CODE (r) != SSA_NAME)
5134 : 0 : continue;
5135 : 339 : if (uaddc_is_cplxpart (SSA_NAME_DEF_STMT (r),
5136 : : REALPART_EXPR))
5137 : : {
5138 : : /* Punt if one of the args which isn't
5139 : : subtracted isn't __real__; that could
5140 : : then prevent better match later.
5141 : : Consider:
5142 : : _3 = .ADD_OVERFLOW (_1, _2);
5143 : : _4 = REALPART_EXPR <_3>;
5144 : : _5 = IMAGPART_EXPR <_3>;
5145 : : _7 = .ADD_OVERFLOW (_4, _6);
5146 : : _8 = REALPART_EXPR <_7>;
5147 : : _9 = IMAGPART_EXPR <_7>;
5148 : : _12 = _10 + _11;
5149 : : _13 = _12 + _9;
5150 : : _14 = _13 + _5;
5151 : : We want to match this when called on
5152 : : the last stmt as a pair of .UADDC calls,
5153 : : but without this check we could turn
5154 : : that prematurely on _13 = _12 + _9;
5155 : : stmt into .UADDC with 0 carry-in just
5156 : : on the second .ADD_OVERFLOW call and
5157 : : another replacing the _12 and _13
5158 : : additions. */
5159 : : ovf_lhs = NULL_TREE;
5160 : : break;
5161 : : }
5162 : : }
5163 : : }
5164 : 190 : if (ovf_lhs)
5165 : : {
5166 : 140 : use_operand_p use_p;
5167 : 140 : imm_use_iterator iter;
5168 : 140 : tree re_lhs = NULL_TREE;
5169 : 420 : FOR_EACH_IMM_USE_FAST (use_p, iter, ovf_lhs)
5170 : : {
5171 : 280 : gimple *use_stmt = USE_STMT (use_p);
5172 : 280 : if (is_gimple_debug (use_stmt))
5173 : 0 : continue;
5174 : 280 : if (use_stmt == im)
5175 : 140 : continue;
5176 : 140 : if (!uaddc_is_cplxpart (use_stmt,
5177 : : REALPART_EXPR))
5178 : : {
5179 : : ovf_lhs = NULL_TREE;
5180 : : break;
5181 : : }
5182 : 140 : re_lhs = gimple_assign_lhs (use_stmt);
5183 : : }
5184 : 140 : if (ovf_lhs && re_lhs)
5185 : : {
5186 : 362 : FOR_EACH_IMM_USE_FAST (use_p, iter, re_lhs)
5187 : : {
5188 : 281 : gimple *use_stmt = USE_STMT (use_p);
5189 : 281 : if (is_gimple_debug (use_stmt))
5190 : 103 : continue;
5191 : 178 : internal_fn ifn
5192 : 178 : = gimple_call_internal_fn (ovf);
5193 : : /* Punt if the __real__ of lhs is used
5194 : : in the same .*_OVERFLOW call.
5195 : : Consider:
5196 : : _3 = .ADD_OVERFLOW (_1, _2);
5197 : : _4 = REALPART_EXPR <_3>;
5198 : : _5 = IMAGPART_EXPR <_3>;
5199 : : _7 = .ADD_OVERFLOW (_4, _6);
5200 : : _8 = REALPART_EXPR <_7>;
5201 : : _9 = IMAGPART_EXPR <_7>;
5202 : : _12 = _10 + _11;
5203 : : _13 = _12 + _5;
5204 : : _14 = _13 + _9;
5205 : : We want to match this when called on
5206 : : the last stmt as a pair of .UADDC calls,
5207 : : but without this check we could turn
5208 : : that prematurely on _13 = _12 + _5;
5209 : : stmt into .UADDC with 0 carry-in just
5210 : : on the first .ADD_OVERFLOW call and
5211 : : another replacing the _12 and _13
5212 : : additions. */
5213 : 178 : if (gimple_call_internal_p (use_stmt, ifn))
5214 : : {
5215 : : ovf_lhs = NULL_TREE;
5216 : : break;
5217 : : }
5218 : : }
5219 : : }
5220 : : }
5221 : : }
5222 : 140 : if ((ovf_lhs
5223 : 143 : || gimple_call_internal_p (ovf,
5224 : : code == PLUS_EXPR
5225 : : ? IFN_UADDC : IFN_USUBC))
5226 : 241 : && (optab_handler (code == PLUS_EXPR
5227 : : ? uaddc5_optab : usubc5_optab,
5228 : 87 : TYPE_MODE (type))
5229 : : != CODE_FOR_nothing))
5230 : : {
5231 : : /* And in that case build another .UADDC/.USUBC
5232 : : call for the most significand limb addition.
5233 : : Overflow bit is ignored here. */
5234 : 63 : if (i != 2)
5235 : 63 : std::swap (rhs[i], rhs[2]);
5236 : 63 : gimple *g
5237 : 77 : = gimple_build_call_internal (code == PLUS_EXPR
5238 : : ? IFN_UADDC
5239 : : : IFN_USUBC,
5240 : : 3, rhs[0], rhs[1],
5241 : : rhs[2]);
5242 : 63 : tree nlhs = make_ssa_name (build_complex_type (type));
5243 : 63 : gimple_call_set_lhs (g, nlhs);
5244 : 63 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5245 : 63 : tree ilhs = gimple_assign_lhs (stmt);
5246 : 63 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5247 : : build1 (REALPART_EXPR,
5248 : 63 : TREE_TYPE (ilhs),
5249 : : nlhs));
5250 : 63 : gsi_replace (gsi, g, true);
5251 : : /* And if it is initialized from result of __imag__
5252 : : of .{ADD,SUB}_OVERFLOW call, replace that
5253 : : call with .U{ADD,SUB}C call with the same arguments,
5254 : : just 0 added as third argument. This isn't strictly
5255 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5256 : : produce the same result, but may result in better
5257 : : generated code on some targets where the backend can
5258 : : better prepare in how the result will be used. */
5259 : 63 : if (ovf_lhs)
5260 : : {
5261 : 57 : tree zero = build_zero_cst (type);
5262 : 57 : g = gimple_build_call_internal (code == PLUS_EXPR
5263 : : ? IFN_UADDC
5264 : : : IFN_USUBC,
5265 : : 3, ovf_arg1,
5266 : : ovf_arg2, zero);
5267 : 57 : gimple_call_set_lhs (g, ovf_lhs);
5268 : 57 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf);
5269 : 57 : gsi_replace (&gsi2, g, true);
5270 : : }
5271 : 63 : return true;
5272 : : }
5273 : : }
5274 : : }
5275 : : return false;
5276 : : }
5277 : 1358048 : if (code == MINUS_EXPR && !rhs[2])
5278 : : return false;
5279 : 249 : if (code == MINUS_EXPR)
5280 : : /* Code below expects rhs[0] and rhs[1] to have the IMAGPART_EXPRs.
5281 : : So, for MINUS_EXPR swap the single added rhs operand (others are
5282 : : subtracted) to rhs[3]. */
5283 : 249 : std::swap (rhs[0], rhs[3]);
5284 : : }
5285 : : /* Walk from both operands of STMT (for +/- even sometimes from
5286 : : all the 4 addends or 3 subtrahends), see through casts and != 0
5287 : : statements which would preserve [0, 1] range of values and
5288 : : check which is initialized from __imag__. */
5289 : 7071090 : gimple *im1 = NULL, *im2 = NULL;
5290 : 14141186 : for (int i = 0; i < (code == MINUS_EXPR ? 3 : 4); i++)
5291 : 5656985 : if (rhs[i] && TREE_CODE (rhs[i]) == SSA_NAME)
5292 : : {
5293 : 1845591 : gimple *im = uaddc_cast (SSA_NAME_DEF_STMT (rhs[i]));
5294 : 1845591 : im = uaddc_ne0 (im);
5295 : 1845591 : if (uaddc_is_cplxpart (im, IMAGPART_EXPR))
5296 : : {
5297 : 1672 : if (im1 == NULL)
5298 : : {
5299 : 1280 : im1 = im;
5300 : 1280 : if (i != 0)
5301 : 371 : std::swap (rhs[0], rhs[i]);
5302 : : }
5303 : : else
5304 : : {
5305 : 392 : im2 = im;
5306 : 392 : if (i != 1)
5307 : 22 : std::swap (rhs[1], rhs[i]);
5308 : : break;
5309 : : }
5310 : : }
5311 : : }
5312 : : /* If we don't find at least two, punt. */
5313 : 1414497 : if (!im2)
5314 : : return false;
5315 : : /* Check they are __imag__ of .ADD_OVERFLOW or .SUB_OVERFLOW call results,
5316 : : either both .ADD_OVERFLOW or both .SUB_OVERFLOW and that we have
5317 : : uaddc5/usubc5 named pattern for the corresponding mode. */
5318 : 392 : gimple *ovf1
5319 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im1), 0));
5320 : 392 : gimple *ovf2
5321 : 392 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im2), 0));
5322 : 392 : internal_fn ifn;
5323 : 392 : if (!is_gimple_call (ovf1)
5324 : 392 : || !gimple_call_internal_p (ovf1)
5325 : 392 : || ((ifn = gimple_call_internal_fn (ovf1)) != IFN_ADD_OVERFLOW
5326 : 59 : && ifn != IFN_SUB_OVERFLOW)
5327 : 369 : || !gimple_call_internal_p (ovf2, ifn)
5328 : 397 : || optab_handler (ifn == IFN_ADD_OVERFLOW ? uaddc5_optab : usubc5_optab,
5329 : 365 : TYPE_MODE (type)) == CODE_FOR_nothing
5330 : 485 : || (rhs[2]
5331 : 17 : && optab_handler (code == PLUS_EXPR ? uaddc5_optab : usubc5_optab,
5332 : 15 : TYPE_MODE (type)) == CODE_FOR_nothing))
5333 : 299 : return false;
5334 : 93 : tree arg1, arg2, arg3 = NULL_TREE;
5335 : 93 : gimple *re1 = NULL, *re2 = NULL;
5336 : : /* On one of the two calls, one of the .ADD_OVERFLOW/.SUB_OVERFLOW arguments
5337 : : should be initialized from __real__ of the other of the two calls.
5338 : : Though, for .SUB_OVERFLOW, it has to be the first argument, not the
5339 : : second one. */
5340 : 340 : for (int i = (ifn == IFN_ADD_OVERFLOW ? 1 : 0); i >= 0; --i)
5341 : 349 : for (gimple *ovf = ovf1; ovf; ovf = (ovf == ovf1 ? ovf2 : NULL))
5342 : : {
5343 : 288 : tree arg = gimple_call_arg (ovf, i);
5344 : 288 : if (TREE_CODE (arg) != SSA_NAME)
5345 : 2 : continue;
5346 : 286 : re1 = SSA_NAME_DEF_STMT (arg);
5347 : 286 : if (uaddc_is_cplxpart (re1, REALPART_EXPR)
5348 : 379 : && (SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (re1), 0))
5349 : 93 : == (ovf == ovf1 ? ovf2 : ovf1)))
5350 : : {
5351 : 93 : if (ovf == ovf1)
5352 : : {
5353 : : /* Make sure ovf2 is the .*_OVERFLOW call with argument
5354 : : initialized from __real__ of ovf1. */
5355 : 20 : std::swap (rhs[0], rhs[1]);
5356 : 20 : std::swap (im1, im2);
5357 : 20 : std::swap (ovf1, ovf2);
5358 : : }
5359 : 93 : arg3 = gimple_call_arg (ovf, 1 - i);
5360 : 93 : i = -1;
5361 : 93 : break;
5362 : : }
5363 : : }
5364 : 93 : if (!arg3)
5365 : : return false;
5366 : 93 : arg1 = gimple_call_arg (ovf1, 0);
5367 : 93 : arg2 = gimple_call_arg (ovf1, 1);
5368 : 93 : if (!types_compatible_p (type, TREE_TYPE (arg1)))
5369 : : return false;
5370 : 93 : int kind[2] = { 0, 0 };
5371 : 93 : tree arg_im[2] = { NULL_TREE, NULL_TREE };
5372 : : /* At least one of arg2 and arg3 should have type compatible
5373 : : with arg1/rhs[0], and the other one should have value in [0, 1]
5374 : : range. If both are in [0, 1] range and type compatible with
5375 : : arg1/rhs[0], try harder to find after looking through casts,
5376 : : != 0 comparisons which one is initialized to __imag__ of
5377 : : .{ADD,SUB}_OVERFLOW or .U{ADD,SUB}C call results. */
5378 : 279 : for (int i = 0; i < 2; ++i)
5379 : : {
5380 : 186 : tree arg = i == 0 ? arg2 : arg3;
5381 : 186 : if (types_compatible_p (type, TREE_TYPE (arg)))
5382 : 161 : kind[i] = 1;
5383 : 372 : if (!INTEGRAL_TYPE_P (TREE_TYPE (arg))
5384 : 372 : || (TYPE_PRECISION (TREE_TYPE (arg)) == 1
5385 : 25 : && !TYPE_UNSIGNED (TREE_TYPE (arg))))
5386 : 0 : continue;
5387 : 186 : if (tree_zero_one_valued_p (arg))
5388 : 51 : kind[i] |= 2;
5389 : 186 : if (TREE_CODE (arg) == SSA_NAME)
5390 : : {
5391 : 184 : gimple *g = SSA_NAME_DEF_STMT (arg);
5392 : 184 : if (gimple_assign_cast_p (g))
5393 : : {
5394 : 30 : tree op = gimple_assign_rhs1 (g);
5395 : 30 : if (TREE_CODE (op) == SSA_NAME
5396 : 30 : && INTEGRAL_TYPE_P (TREE_TYPE (op)))
5397 : 30 : g = SSA_NAME_DEF_STMT (op);
5398 : : }
5399 : 184 : g = uaddc_ne0 (g);
5400 : 184 : if (!uaddc_is_cplxpart (g, IMAGPART_EXPR))
5401 : 124 : continue;
5402 : 60 : arg_im[i] = gimple_assign_lhs (g);
5403 : 60 : g = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (g), 0));
5404 : 60 : if (!is_gimple_call (g) || !gimple_call_internal_p (g))
5405 : 0 : continue;
5406 : 60 : switch (gimple_call_internal_fn (g))
5407 : : {
5408 : 60 : case IFN_ADD_OVERFLOW:
5409 : 60 : case IFN_SUB_OVERFLOW:
5410 : 60 : case IFN_UADDC:
5411 : 60 : case IFN_USUBC:
5412 : 60 : break;
5413 : 0 : default:
5414 : 0 : continue;
5415 : : }
5416 : 60 : kind[i] |= 4;
5417 : : }
5418 : : }
5419 : : /* Make arg2 the one with compatible type and arg3 the one
5420 : : with [0, 1] range. If both is true for both operands,
5421 : : prefer as arg3 result of __imag__ of some ifn. */
5422 : 93 : if ((kind[0] & 1) == 0 || ((kind[1] & 1) != 0 && kind[0] > kind[1]))
5423 : : {
5424 : 1 : std::swap (arg2, arg3);
5425 : 1 : std::swap (kind[0], kind[1]);
5426 : 1 : std::swap (arg_im[0], arg_im[1]);
5427 : : }
5428 : 93 : if ((kind[0] & 1) == 0 || (kind[1] & 6) == 0)
5429 : : return false;
5430 : 69 : if (!has_single_use (gimple_assign_lhs (im1))
5431 : 67 : || !has_single_use (gimple_assign_lhs (im2))
5432 : 67 : || !has_single_use (gimple_assign_lhs (re1))
5433 : 136 : || num_imm_uses (gimple_call_lhs (ovf1)) != 2)
5434 : : return false;
5435 : : /* Check that ovf2's result is used in __real__ and set re2
5436 : : to that statement. */
5437 : 67 : use_operand_p use_p;
5438 : 67 : imm_use_iterator iter;
5439 : 67 : tree lhs = gimple_call_lhs (ovf2);
5440 : 200 : FOR_EACH_IMM_USE_FAST (use_p, iter, lhs)
5441 : : {
5442 : 133 : gimple *use_stmt = USE_STMT (use_p);
5443 : 133 : if (is_gimple_debug (use_stmt))
5444 : 0 : continue;
5445 : 133 : if (use_stmt == im2)
5446 : 67 : continue;
5447 : 66 : if (re2)
5448 : : return false;
5449 : 66 : if (!uaddc_is_cplxpart (use_stmt, REALPART_EXPR))
5450 : : return false;
5451 : : re2 = use_stmt;
5452 : : }
5453 : : /* Build .UADDC/.USUBC call which will be placed before the stmt. */
5454 : 67 : gimple_stmt_iterator gsi2 = gsi_for_stmt (ovf2);
5455 : 67 : gimple *g;
5456 : 67 : if ((kind[1] & 4) != 0 && types_compatible_p (type, TREE_TYPE (arg_im[1])))
5457 : : arg3 = arg_im[1];
5458 : 67 : if ((kind[1] & 1) == 0)
5459 : : {
5460 : 25 : if (TREE_CODE (arg3) == INTEGER_CST)
5461 : 0 : arg3 = fold_convert (type, arg3);
5462 : : else
5463 : : {
5464 : 25 : g = gimple_build_assign (make_ssa_name (type), NOP_EXPR, arg3);
5465 : 25 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5466 : 25 : arg3 = gimple_assign_lhs (g);
5467 : : }
5468 : : }
5469 : 89 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5470 : : ? IFN_UADDC : IFN_USUBC,
5471 : : 3, arg1, arg2, arg3);
5472 : 67 : tree nlhs = make_ssa_name (TREE_TYPE (lhs));
5473 : 67 : gimple_call_set_lhs (g, nlhs);
5474 : 67 : gsi_insert_before (&gsi2, g, GSI_SAME_STMT);
5475 : : /* In the case where stmt is | or ^ of two overflow flags
5476 : : or addition of those, replace stmt with __imag__ of the above
5477 : : added call. In case of arg1 + arg2 + (ovf1 + ovf2) or
5478 : : arg1 - arg2 - (ovf1 + ovf2) just emit it before stmt. */
5479 : 67 : tree ilhs = rhs[2] ? make_ssa_name (type) : gimple_assign_lhs (stmt);
5480 : 67 : g = gimple_build_assign (ilhs, IMAGPART_EXPR,
5481 : 67 : build1 (IMAGPART_EXPR, TREE_TYPE (ilhs), nlhs));
5482 : 67 : if (rhs[2])
5483 : : {
5484 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5485 : : /* Remove some further statements which can't be kept in the IL because
5486 : : they can use SSA_NAMEs whose setter is going to be removed too. */
5487 : 75 : for (gimple *g2 : temp_stmts)
5488 : : {
5489 : 30 : gsi2 = gsi_for_stmt (g2);
5490 : 30 : gsi_remove (&gsi2, true);
5491 : 30 : release_defs (g2);
5492 : : }
5493 : : }
5494 : : else
5495 : 52 : gsi_replace (gsi, g, true);
5496 : : /* Remove some statements which can't be kept in the IL because they
5497 : : use SSA_NAME whose setter is going to be removed too. */
5498 : 67 : tree rhs1 = rhs[1];
5499 : 103 : for (int i = 0; i < 2; i++)
5500 : 85 : if (rhs1 == gimple_assign_lhs (im2))
5501 : : break;
5502 : : else
5503 : : {
5504 : 36 : g = SSA_NAME_DEF_STMT (rhs1);
5505 : 36 : rhs1 = gimple_assign_rhs1 (g);
5506 : 36 : gsi2 = gsi_for_stmt (g);
5507 : 36 : gsi_remove (&gsi2, true);
5508 : 36 : release_defs (g);
5509 : : }
5510 : 67 : gcc_checking_assert (rhs1 == gimple_assign_lhs (im2));
5511 : 67 : gsi2 = gsi_for_stmt (im2);
5512 : 67 : gsi_remove (&gsi2, true);
5513 : 67 : release_defs (im2);
5514 : : /* Replace the re2 statement with __real__ of the newly added
5515 : : .UADDC/.USUBC call. */
5516 : 67 : if (re2)
5517 : : {
5518 : 66 : gsi2 = gsi_for_stmt (re2);
5519 : 66 : tree rlhs = gimple_assign_lhs (re2);
5520 : 66 : g = gimple_build_assign (rlhs, REALPART_EXPR,
5521 : 66 : build1 (REALPART_EXPR, TREE_TYPE (rlhs), nlhs));
5522 : 66 : gsi_replace (&gsi2, g, true);
5523 : : }
5524 : 67 : if (rhs[2])
5525 : : {
5526 : : /* If this is the arg1 + arg2 + (ovf1 + ovf2) or
5527 : : arg1 - arg2 - (ovf1 + ovf2) case for the most significant limb,
5528 : : replace stmt with __real__ of another .UADDC/.USUBC call which
5529 : : handles the most significant limb. Overflow flag from this is
5530 : : ignored. */
5531 : 17 : g = gimple_build_call_internal (code == PLUS_EXPR
5532 : : ? IFN_UADDC : IFN_USUBC,
5533 : : 3, rhs[3], rhs[2], ilhs);
5534 : 15 : nlhs = make_ssa_name (TREE_TYPE (lhs));
5535 : 15 : gimple_call_set_lhs (g, nlhs);
5536 : 15 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5537 : 15 : ilhs = gimple_assign_lhs (stmt);
5538 : 15 : g = gimple_build_assign (ilhs, REALPART_EXPR,
5539 : 15 : build1 (REALPART_EXPR, TREE_TYPE (ilhs), nlhs));
5540 : 15 : gsi_replace (gsi, g, true);
5541 : : }
5542 : 67 : if (TREE_CODE (arg3) == SSA_NAME)
5543 : : {
5544 : : /* When pattern recognizing the second least significant limb
5545 : : above (i.e. first pair of .{ADD,SUB}_OVERFLOW calls for one limb),
5546 : : check if the [0, 1] range argument (i.e. carry in) isn't the
5547 : : result of another .{ADD,SUB}_OVERFLOW call (one handling the
5548 : : least significant limb). Again look through casts and != 0. */
5549 : 67 : gimple *im3 = SSA_NAME_DEF_STMT (arg3);
5550 : 92 : for (int i = 0; i < 2; ++i)
5551 : : {
5552 : 92 : gimple *im4 = uaddc_cast (im3);
5553 : 92 : if (im4 == im3)
5554 : : break;
5555 : : else
5556 : 25 : im3 = im4;
5557 : : }
5558 : 67 : im3 = uaddc_ne0 (im3);
5559 : 67 : if (uaddc_is_cplxpart (im3, IMAGPART_EXPR))
5560 : : {
5561 : 60 : gimple *ovf3
5562 : 60 : = SSA_NAME_DEF_STMT (TREE_OPERAND (gimple_assign_rhs1 (im3), 0));
5563 : 60 : if (gimple_call_internal_p (ovf3, ifn))
5564 : : {
5565 : 25 : lhs = gimple_call_lhs (ovf3);
5566 : 25 : arg1 = gimple_call_arg (ovf3, 0);
5567 : 25 : arg2 = gimple_call_arg (ovf3, 1);
5568 : 25 : if (types_compatible_p (type, TREE_TYPE (TREE_TYPE (lhs)))
5569 : 25 : && types_compatible_p (type, TREE_TYPE (arg1))
5570 : 50 : && types_compatible_p (type, TREE_TYPE (arg2)))
5571 : : {
5572 : : /* And if it is initialized from result of __imag__
5573 : : of .{ADD,SUB}_OVERFLOW call, replace that
5574 : : call with .U{ADD,SUB}C call with the same arguments,
5575 : : just 0 added as third argument. This isn't strictly
5576 : : necessary, .ADD_OVERFLOW (x, y) and .UADDC (x, y, 0)
5577 : : produce the same result, but may result in better
5578 : : generated code on some targets where the backend can
5579 : : better prepare in how the result will be used. */
5580 : 25 : g = gimple_build_call_internal (ifn == IFN_ADD_OVERFLOW
5581 : : ? IFN_UADDC : IFN_USUBC,
5582 : : 3, arg1, arg2,
5583 : : build_zero_cst (type));
5584 : 25 : gimple_call_set_lhs (g, lhs);
5585 : 25 : gsi2 = gsi_for_stmt (ovf3);
5586 : 25 : gsi_replace (&gsi2, g, true);
5587 : : }
5588 : : }
5589 : : }
5590 : : }
5591 : : return true;
5592 : 1589765 : }
5593 : :
5594 : : /* Replace .POPCOUNT (x) == 1 or .POPCOUNT (x) != 1 with
5595 : : (x & (x - 1)) > x - 1 or (x & (x - 1)) <= x - 1 if .POPCOUNT
5596 : : isn't a direct optab. Also handle `<=`/`>` to be
5597 : : `x & (x - 1) !=/== x`. */
5598 : :
5599 : : static void
5600 : 4403075 : match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
5601 : : {
5602 : 4403075 : tree clhs, crhs;
5603 : 4403075 : enum tree_code code;
5604 : 4403075 : bool was_le = false;
5605 : 4403075 : if (gimple_code (stmt) == GIMPLE_COND)
5606 : : {
5607 : 4101644 : clhs = gimple_cond_lhs (stmt);
5608 : 4101644 : crhs = gimple_cond_rhs (stmt);
5609 : 4101644 : code = gimple_cond_code (stmt);
5610 : : }
5611 : : else
5612 : : {
5613 : 301431 : clhs = gimple_assign_rhs1 (stmt);
5614 : 301431 : crhs = gimple_assign_rhs2 (stmt);
5615 : 301431 : code = gimple_assign_rhs_code (stmt);
5616 : : }
5617 : 4403075 : if (code != LE_EXPR && code != GT_EXPR
5618 : 4403075 : && code != EQ_EXPR && code != NE_EXPR)
5619 : 4403069 : return;
5620 : 2051217 : if (code == LE_EXPR || code == GT_EXPR)
5621 : 4149616 : was_le = true;
5622 : 4149616 : if (TREE_CODE (clhs) != SSA_NAME || !integer_onep (crhs))
5623 : 3993267 : return;
5624 : 156349 : gimple *call = SSA_NAME_DEF_STMT (clhs);
5625 : 156349 : combined_fn cfn = gimple_call_combined_fn (call);
5626 : 156349 : switch (cfn)
5627 : : {
5628 : 15 : CASE_CFN_POPCOUNT:
5629 : 15 : break;
5630 : : default:
5631 : : return;
5632 : : }
5633 : 15 : if (!has_single_use (clhs))
5634 : : return;
5635 : 14 : tree arg = gimple_call_arg (call, 0);
5636 : 14 : tree type = TREE_TYPE (arg);
5637 : 14 : if (!INTEGRAL_TYPE_P (type))
5638 : : return;
5639 : 14 : bool nonzero_arg = tree_expr_nonzero_p (arg);
5640 : 14 : if (direct_internal_fn_supported_p (IFN_POPCOUNT, type, OPTIMIZE_FOR_BOTH))
5641 : : {
5642 : : /* Tell expand_POPCOUNT the popcount result is only used in equality
5643 : : comparison with one, so that it can decide based on rtx costs. */
5644 : 16 : gimple *g = gimple_build_call_internal (IFN_POPCOUNT, 2, arg,
5645 : : was_le ? integer_minus_one_node
5646 : 8 : : (nonzero_arg ? integer_zero_node
5647 : : : integer_one_node));
5648 : 8 : gimple_call_set_lhs (g, gimple_call_lhs (call));
5649 : 8 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5650 : 8 : gsi_replace (&gsi2, g, true);
5651 : 8 : return;
5652 : : }
5653 : 6 : tree argm1 = make_ssa_name (type);
5654 : 6 : gimple *g = gimple_build_assign (argm1, PLUS_EXPR, arg,
5655 : : build_int_cst (type, -1));
5656 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5657 : 6 : g = gimple_build_assign (make_ssa_name (type),
5658 : 6 : (nonzero_arg || was_le) ? BIT_AND_EXPR : BIT_XOR_EXPR,
5659 : : arg, argm1);
5660 : 6 : gsi_insert_before (gsi, g, GSI_SAME_STMT);
5661 : 6 : tree_code cmpcode;
5662 : 6 : if (was_le)
5663 : : {
5664 : 0 : argm1 = build_zero_cst (type);
5665 : 0 : cmpcode = code == LE_EXPR ? EQ_EXPR : NE_EXPR;
5666 : : }
5667 : 6 : else if (nonzero_arg)
5668 : : {
5669 : 2 : argm1 = build_zero_cst (type);
5670 : 2 : cmpcode = code;
5671 : : }
5672 : : else
5673 : 4 : cmpcode = code == EQ_EXPR ? GT_EXPR : LE_EXPR;
5674 : 6 : if (gcond *cond = dyn_cast <gcond *> (stmt))
5675 : : {
5676 : 2 : gimple_cond_set_lhs (cond, gimple_assign_lhs (g));
5677 : 2 : gimple_cond_set_rhs (cond, argm1);
5678 : 2 : gimple_cond_set_code (cond, cmpcode);
5679 : : }
5680 : : else
5681 : : {
5682 : 4 : gimple_assign_set_rhs1 (stmt, gimple_assign_lhs (g));
5683 : 4 : gimple_assign_set_rhs2 (stmt, argm1);
5684 : 4 : gimple_assign_set_rhs_code (stmt, cmpcode);
5685 : : }
5686 : 6 : update_stmt (stmt);
5687 : 6 : gimple_stmt_iterator gsi2 = gsi_for_stmt (call);
5688 : 6 : gsi_remove (&gsi2, true);
5689 : 6 : release_defs (call);
5690 : : }
5691 : :
5692 : : /* Return true if target has support for divmod. */
5693 : :
5694 : : static bool
5695 : 27765 : target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
5696 : : {
5697 : : /* If target supports hardware divmod insn, use it for divmod. */
5698 : 27765 : if (optab_handler (divmod_optab, mode) != CODE_FOR_nothing)
5699 : : return true;
5700 : :
5701 : : /* Check if libfunc for divmod is available. */
5702 : 2672 : rtx libfunc = optab_libfunc (divmod_optab, mode);
5703 : 2672 : if (libfunc != NULL_RTX)
5704 : : {
5705 : : /* If optab_handler exists for div_optab, perhaps in a wider mode,
5706 : : we don't want to use the libfunc even if it exists for given mode. */
5707 : : machine_mode div_mode;
5708 : 11120 : FOR_EACH_MODE_FROM (div_mode, mode)
5709 : 8448 : if (optab_handler (div_optab, div_mode) != CODE_FOR_nothing)
5710 : : return false;
5711 : :
5712 : 2672 : return targetm.expand_divmod_libfunc != NULL;
5713 : : }
5714 : :
5715 : : return false;
5716 : : }
5717 : :
5718 : : /* Check if stmt is candidate for divmod transform. */
5719 : :
5720 : : static bool
5721 : 48480 : divmod_candidate_p (gassign *stmt)
5722 : : {
5723 : 48480 : tree type = TREE_TYPE (gimple_assign_lhs (stmt));
5724 : 48480 : machine_mode mode = TYPE_MODE (type);
5725 : 48480 : optab divmod_optab, div_optab;
5726 : :
5727 : 48480 : if (TYPE_UNSIGNED (type))
5728 : : {
5729 : : divmod_optab = udivmod_optab;
5730 : : div_optab = udiv_optab;
5731 : : }
5732 : : else
5733 : : {
5734 : 19857 : divmod_optab = sdivmod_optab;
5735 : 19857 : div_optab = sdiv_optab;
5736 : : }
5737 : :
5738 : 48480 : tree op1 = gimple_assign_rhs1 (stmt);
5739 : 48480 : tree op2 = gimple_assign_rhs2 (stmt);
5740 : :
5741 : : /* Disable the transform if either is a constant, since division-by-constant
5742 : : may have specialized expansion. */
5743 : 48480 : if (CONSTANT_CLASS_P (op1))
5744 : : return false;
5745 : :
5746 : 44830 : if (CONSTANT_CLASS_P (op2))
5747 : : {
5748 : 19384 : if (integer_pow2p (op2))
5749 : : return false;
5750 : :
5751 : 16986 : if (element_precision (type) <= HOST_BITS_PER_WIDE_INT
5752 : 18067 : && element_precision (type) <= BITS_PER_WORD)
5753 : : return false;
5754 : :
5755 : : /* If the divisor is not power of 2 and the precision wider than
5756 : : HWI, expand_divmod punts on that, so in that case it is better
5757 : : to use divmod optab or libfunc. Similarly if choose_multiplier
5758 : : might need pre/post shifts of BITS_PER_WORD or more. */
5759 : : }
5760 : :
5761 : : /* Exclude the case where TYPE_OVERFLOW_TRAPS (type) as that should
5762 : : expand using the [su]divv optabs. */
5763 : 27765 : if (TYPE_OVERFLOW_TRAPS (type))
5764 : : return false;
5765 : :
5766 : 27765 : if (!target_supports_divmod_p (divmod_optab, div_optab, mode))
5767 : : return false;
5768 : :
5769 : : return true;
5770 : : }
5771 : :
5772 : : /* This function looks for:
5773 : : t1 = a TRUNC_DIV_EXPR b;
5774 : : t2 = a TRUNC_MOD_EXPR b;
5775 : : and transforms it to the following sequence:
5776 : : complex_tmp = DIVMOD (a, b);
5777 : : t1 = REALPART_EXPR(a);
5778 : : t2 = IMAGPART_EXPR(b);
5779 : : For conditions enabling the transform see divmod_candidate_p().
5780 : :
5781 : : The pass has three parts:
5782 : : 1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
5783 : : other trunc_div_expr and trunc_mod_expr stmts.
5784 : : 2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
5785 : : to stmts vector.
5786 : : 3) Insert DIVMOD call just before top_stmt and update entries in
5787 : : stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
5788 : : IMAGPART_EXPR for mod). */
5789 : :
5790 : : static bool
5791 : 48503 : convert_to_divmod (gassign *stmt)
5792 : : {
5793 : 48503 : if (stmt_can_throw_internal (cfun, stmt)
5794 : 48503 : || !divmod_candidate_p (stmt))
5795 : 20738 : return false;
5796 : :
5797 : 27765 : tree op1 = gimple_assign_rhs1 (stmt);
5798 : 27765 : tree op2 = gimple_assign_rhs2 (stmt);
5799 : :
5800 : 27765 : imm_use_iterator use_iter;
5801 : 27765 : gimple *use_stmt;
5802 : 27765 : auto_vec<gimple *> stmts;
5803 : :
5804 : 27765 : gimple *top_stmt = stmt;
5805 : 27765 : basic_block top_bb = gimple_bb (stmt);
5806 : :
5807 : : /* Part 1: Try to set top_stmt to "topmost" stmt that dominates
5808 : : at-least stmt and possibly other trunc_div/trunc_mod stmts
5809 : : having same operands as stmt. */
5810 : :
5811 : 117903 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, op1)
5812 : : {
5813 : 90138 : if (is_gimple_assign (use_stmt)
5814 : 54804 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5815 : 43235 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5816 : 45720 : && operand_equal_p (op1, gimple_assign_rhs1 (use_stmt), 0)
5817 : 135741 : && operand_equal_p (op2, gimple_assign_rhs2 (use_stmt), 0))
5818 : : {
5819 : 39254 : if (stmt_can_throw_internal (cfun, use_stmt))
5820 : 0 : continue;
5821 : :
5822 : 39254 : basic_block bb = gimple_bb (use_stmt);
5823 : :
5824 : 39254 : if (bb == top_bb)
5825 : : {
5826 : 38517 : if (gimple_uid (use_stmt) < gimple_uid (top_stmt))
5827 : 5184 : top_stmt = use_stmt;
5828 : : }
5829 : 737 : else if (dominated_by_p (CDI_DOMINATORS, top_bb, bb))
5830 : : {
5831 : 190 : top_bb = bb;
5832 : 190 : top_stmt = use_stmt;
5833 : : }
5834 : : }
5835 : 27765 : }
5836 : :
5837 : 27765 : tree top_op1 = gimple_assign_rhs1 (top_stmt);
5838 : 27765 : tree top_op2 = gimple_assign_rhs2 (top_stmt);
5839 : :
5840 : 27765 : stmts.safe_push (top_stmt);
5841 : 27765 : bool div_seen = (gimple_assign_rhs_code (top_stmt) == TRUNC_DIV_EXPR);
5842 : :
5843 : : /* Part 2: Add all trunc_div/trunc_mod statements domianted by top_bb
5844 : : to stmts vector. The 2nd loop will always add stmt to stmts vector, since
5845 : : gimple_bb (top_stmt) dominates gimple_bb (stmt), so the
5846 : : 2nd loop ends up adding at-least single trunc_mod_expr stmt. */
5847 : :
5848 : 117903 : FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, top_op1)
5849 : : {
5850 : 90138 : if (is_gimple_assign (use_stmt)
5851 : 54804 : && (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR
5852 : 43235 : || gimple_assign_rhs_code (use_stmt) == TRUNC_MOD_EXPR)
5853 : 45720 : && operand_equal_p (top_op1, gimple_assign_rhs1 (use_stmt), 0)
5854 : 135741 : && operand_equal_p (top_op2, gimple_assign_rhs2 (use_stmt), 0))
5855 : : {
5856 : 67119 : if (use_stmt == top_stmt
5857 : 11489 : || stmt_can_throw_internal (cfun, use_stmt)
5858 : 50743 : || !dominated_by_p (CDI_DOMINATORS, gimple_bb (use_stmt), top_bb))
5859 : 27865 : continue;
5860 : :
5861 : 11389 : stmts.safe_push (use_stmt);
5862 : 11389 : if (gimple_assign_rhs_code (use_stmt) == TRUNC_DIV_EXPR)
5863 : 90138 : div_seen = true;
5864 : : }
5865 : 27765 : }
5866 : :
5867 : 27765 : if (!div_seen)
5868 : : return false;
5869 : :
5870 : : /* Part 3: Create libcall to internal fn DIVMOD:
5871 : : divmod_tmp = DIVMOD (op1, op2). */
5872 : :
5873 : 11363 : gcall *call_stmt = gimple_build_call_internal (IFN_DIVMOD, 2, op1, op2);
5874 : 11363 : tree res = make_temp_ssa_name (build_complex_type (TREE_TYPE (op1)),
5875 : : call_stmt, "divmod_tmp");
5876 : 11363 : gimple_call_set_lhs (call_stmt, res);
5877 : : /* We rejected throwing statements above. */
5878 : 11363 : gimple_call_set_nothrow (call_stmt, true);
5879 : :
5880 : : /* Insert the call before top_stmt. */
5881 : 11363 : gimple_stmt_iterator top_stmt_gsi = gsi_for_stmt (top_stmt);
5882 : 11363 : gsi_insert_before (&top_stmt_gsi, call_stmt, GSI_SAME_STMT);
5883 : :
5884 : 11363 : widen_mul_stats.divmod_calls_inserted++;
5885 : :
5886 : : /* Update all statements in stmts vector:
5887 : : lhs = op1 TRUNC_DIV_EXPR op2 -> lhs = REALPART_EXPR<divmod_tmp>
5888 : : lhs = op1 TRUNC_MOD_EXPR op2 -> lhs = IMAGPART_EXPR<divmod_tmp>. */
5889 : :
5890 : 61878 : for (unsigned i = 0; stmts.iterate (i, &use_stmt); ++i)
5891 : : {
5892 : 22750 : tree new_rhs;
5893 : :
5894 : 22750 : switch (gimple_assign_rhs_code (use_stmt))
5895 : : {
5896 : 11373 : case TRUNC_DIV_EXPR:
5897 : 11373 : new_rhs = fold_build1 (REALPART_EXPR, TREE_TYPE (op1), res);
5898 : 11373 : break;
5899 : :
5900 : 11377 : case TRUNC_MOD_EXPR:
5901 : 11377 : new_rhs = fold_build1 (IMAGPART_EXPR, TREE_TYPE (op1), res);
5902 : 11377 : break;
5903 : :
5904 : 0 : default:
5905 : 0 : gcc_unreachable ();
5906 : : }
5907 : :
5908 : 22750 : gimple_stmt_iterator gsi = gsi_for_stmt (use_stmt);
5909 : 22750 : gimple_assign_set_rhs_from_tree (&gsi, new_rhs);
5910 : 22750 : update_stmt (use_stmt);
5911 : : }
5912 : :
5913 : : return true;
5914 : 27765 : }
5915 : :
5916 : : /* Process a single gimple assignment STMT, which has a RSHIFT_EXPR as
5917 : : its rhs, and try to convert it into a MULT_HIGHPART_EXPR. The return
5918 : : value is true iff we converted the statement. */
5919 : :
5920 : : static bool
5921 : 169926 : convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
5922 : : {
5923 : 169926 : tree lhs = gimple_assign_lhs (stmt);
5924 : 169926 : tree stype = TREE_TYPE (lhs);
5925 : 169926 : tree sarg0 = gimple_assign_rhs1 (stmt);
5926 : 169926 : tree sarg1 = gimple_assign_rhs2 (stmt);
5927 : :
5928 : 169926 : if (TREE_CODE (stype) != INTEGER_TYPE
5929 : 163674 : || TREE_CODE (sarg1) != INTEGER_CST
5930 : 147740 : || TREE_CODE (sarg0) != SSA_NAME
5931 : 147739 : || !tree_fits_uhwi_p (sarg1)
5932 : 317665 : || !has_single_use (sarg0))
5933 : : return false;
5934 : :
5935 : 39118 : gassign *def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (sarg0));
5936 : 36247 : if (!def)
5937 : : return false;
5938 : :
5939 : 36247 : enum tree_code mcode = gimple_assign_rhs_code (def);
5940 : 36247 : if (mcode == NOP_EXPR)
5941 : : {
5942 : 5582 : tree tmp = gimple_assign_rhs1 (def);
5943 : 5582 : if (TREE_CODE (tmp) != SSA_NAME || !has_single_use (tmp))
5944 : : return false;
5945 : 170675 : def = dyn_cast <gassign *> (SSA_NAME_DEF_STMT (tmp));
5946 : 1589 : if (!def)
5947 : : return false;
5948 : 1589 : mcode = gimple_assign_rhs_code (def);
5949 : : }
5950 : :
5951 : 32254 : if (mcode != WIDEN_MULT_EXPR
5952 : 32254 : || gimple_bb (def) != gimple_bb (stmt))
5953 : : return false;
5954 : 841 : tree mtype = TREE_TYPE (gimple_assign_lhs (def));
5955 : 841 : if (TREE_CODE (mtype) != INTEGER_TYPE
5956 : 841 : || TYPE_PRECISION (mtype) != TYPE_PRECISION (stype))
5957 : : return false;
5958 : :
5959 : 841 : tree mop1 = gimple_assign_rhs1 (def);
5960 : 841 : tree mop2 = gimple_assign_rhs2 (def);
5961 : 841 : tree optype = TREE_TYPE (mop1);
5962 : 841 : bool unsignedp = TYPE_UNSIGNED (optype);
5963 : 841 : unsigned int prec = TYPE_PRECISION (optype);
5964 : :
5965 : 841 : if (unsignedp != TYPE_UNSIGNED (mtype)
5966 : 841 : || TYPE_PRECISION (mtype) != 2 * prec)
5967 : : return false;
5968 : :
5969 : 841 : unsigned HOST_WIDE_INT bits = tree_to_uhwi (sarg1);
5970 : 841 : if (bits < prec || bits >= 2 * prec)
5971 : : return false;
5972 : :
5973 : : /* For the time being, require operands to have the same sign. */
5974 : 840 : if (unsignedp != TYPE_UNSIGNED (TREE_TYPE (mop2)))
5975 : : return false;
5976 : :
5977 : 840 : machine_mode mode = TYPE_MODE (optype);
5978 : 840 : optab tab = unsignedp ? umul_highpart_optab : smul_highpart_optab;
5979 : 840 : if (optab_handler (tab, mode) == CODE_FOR_nothing)
5980 : : return false;
5981 : :
5982 : 840 : location_t loc = gimple_location (stmt);
5983 : 840 : tree highpart1 = build_and_insert_binop (gsi, loc, "highparttmp",
5984 : : MULT_HIGHPART_EXPR, mop1, mop2);
5985 : 840 : tree highpart2 = highpart1;
5986 : 840 : tree ntype = optype;
5987 : :
5988 : 840 : if (TYPE_UNSIGNED (stype) != TYPE_UNSIGNED (optype))
5989 : : {
5990 : 16 : ntype = TYPE_UNSIGNED (stype) ? unsigned_type_for (optype)
5991 : 7 : : signed_type_for (optype);
5992 : 16 : highpart2 = build_and_insert_cast (gsi, loc, ntype, highpart1);
5993 : : }
5994 : 840 : if (bits > prec)
5995 : 29 : highpart2 = build_and_insert_binop (gsi, loc, "highparttmp",
5996 : : RSHIFT_EXPR, highpart2,
5997 : 29 : build_int_cst (ntype, bits - prec));
5998 : :
5999 : 840 : gassign *new_stmt = gimple_build_assign (lhs, NOP_EXPR, highpart2);
6000 : 840 : gsi_replace (gsi, new_stmt, true);
6001 : :
6002 : 840 : widen_mul_stats.highpart_mults_inserted++;
6003 : 840 : return true;
6004 : : }
6005 : :
6006 : : /* If target has spaceship<MODE>3 expander, pattern recognize
6007 : : <bb 2> [local count: 1073741824]:
6008 : : if (a_2(D) == b_3(D))
6009 : : goto <bb 6>; [34.00%]
6010 : : else
6011 : : goto <bb 3>; [66.00%]
6012 : :
6013 : : <bb 3> [local count: 708669601]:
6014 : : if (a_2(D) < b_3(D))
6015 : : goto <bb 6>; [1.04%]
6016 : : else
6017 : : goto <bb 4>; [98.96%]
6018 : :
6019 : : <bb 4> [local count: 701299439]:
6020 : : if (a_2(D) > b_3(D))
6021 : : goto <bb 5>; [48.89%]
6022 : : else
6023 : : goto <bb 6>; [51.11%]
6024 : :
6025 : : <bb 5> [local count: 342865295]:
6026 : :
6027 : : <bb 6> [local count: 1073741824]:
6028 : : and turn it into:
6029 : : <bb 2> [local count: 1073741824]:
6030 : : _1 = .SPACESHIP (a_2(D), b_3(D), 0);
6031 : : if (_1 == 0)
6032 : : goto <bb 6>; [34.00%]
6033 : : else
6034 : : goto <bb 3>; [66.00%]
6035 : :
6036 : : <bb 3> [local count: 708669601]:
6037 : : if (_1 == -1)
6038 : : goto <bb 6>; [1.04%]
6039 : : else
6040 : : goto <bb 4>; [98.96%]
6041 : :
6042 : : <bb 4> [local count: 701299439]:
6043 : : if (_1 == 1)
6044 : : goto <bb 5>; [48.89%]
6045 : : else
6046 : : goto <bb 6>; [51.11%]
6047 : :
6048 : : <bb 5> [local count: 342865295]:
6049 : :
6050 : : <bb 6> [local count: 1073741824]:
6051 : : so that the backend can emit optimal comparison and
6052 : : conditional jump sequence. If the
6053 : : <bb 6> [local count: 1073741824]:
6054 : : above has a single PHI like:
6055 : : # _27 = PHI<0(2), -1(3), 2(4), 1(5)>
6056 : : then replace it with effectively
6057 : : _1 = .SPACESHIP (a_2(D), b_3(D), 1);
6058 : : _27 = _1; */
6059 : :
6060 : : static void
6061 : 4101644 : optimize_spaceship (gcond *stmt)
6062 : : {
6063 : 4101644 : enum tree_code code = gimple_cond_code (stmt);
6064 : 4101644 : if (code != EQ_EXPR && code != NE_EXPR)
6065 : 4101446 : return;
6066 : 3328114 : tree arg1 = gimple_cond_lhs (stmt);
6067 : 3328114 : tree arg2 = gimple_cond_rhs (stmt);
6068 : 3328114 : if ((!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1))
6069 : 3219514 : && !INTEGRAL_TYPE_P (TREE_TYPE (arg1)))
6070 : 2610246 : || optab_handler (spaceship_optab,
6071 : 2610246 : TYPE_MODE (TREE_TYPE (arg1))) == CODE_FOR_nothing
6072 : 5897636 : || operand_equal_p (arg1, arg2, 0))
6073 : 759654 : return;
6074 : :
6075 : 2568460 : basic_block bb0 = gimple_bb (stmt), bb1, bb2 = NULL;
6076 : 2568460 : edge em1 = NULL, e1 = NULL, e2 = NULL;
6077 : 2568460 : bb1 = EDGE_SUCC (bb0, 1)->dest;
6078 : 2568460 : if (((EDGE_SUCC (bb0, 0)->flags & EDGE_TRUE_VALUE) != 0) ^ (code == EQ_EXPR))
6079 : 1539392 : bb1 = EDGE_SUCC (bb0, 0)->dest;
6080 : :
6081 : 7552427 : gcond *g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb1));
6082 : 1095140 : if (g == NULL
6083 : 1095140 : || !single_pred_p (bb1)
6084 : 710930 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6085 : 591763 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6086 : 472596 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6087 : 1744 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6088 : 602666 : || !cond_only_block_p (bb1))
6089 : 2558343 : return;
6090 : :
6091 : 10117 : enum tree_code ccode = (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6092 : 10117 : ? LT_EXPR : GT_EXPR);
6093 : 10117 : switch (gimple_cond_code (g))
6094 : : {
6095 : : case LT_EXPR:
6096 : : case LE_EXPR:
6097 : : break;
6098 : 7717 : case GT_EXPR:
6099 : 7717 : case GE_EXPR:
6100 : 7717 : ccode = ccode == LT_EXPR ? GT_EXPR : LT_EXPR;
6101 : : break;
6102 : : default:
6103 : : return;
6104 : : }
6105 : :
6106 : 30248 : for (int i = 0; i < 2; ++i)
6107 : : {
6108 : : /* With NaNs, </<=/>/>= are false, so we need to look for the
6109 : : third comparison on the false edge from whatever non-equality
6110 : : comparison the second comparison is. */
6111 : 20222 : if (HONOR_NANS (TREE_TYPE (arg1))
6112 : 20222 : && (EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0)
6113 : 205 : continue;
6114 : :
6115 : 20017 : bb2 = EDGE_SUCC (bb1, i)->dest;
6116 : 59472 : g = safe_dyn_cast <gcond *> (*gsi_last_bb (bb2));
6117 : 12867 : if (g == NULL
6118 : 12867 : || !single_pred_p (bb2)
6119 : 17595 : || (operand_equal_p (gimple_cond_lhs (g), arg1, 0)
6120 : 9896 : ? !operand_equal_p (gimple_cond_rhs (g), arg2, 0)
6121 : 2197 : : (!operand_equal_p (gimple_cond_lhs (g), arg2, 0)
6122 : 12 : || !operand_equal_p (gimple_cond_rhs (g), arg1, 0)))
6123 : 88 : || !cond_only_block_p (bb2)
6124 : 9984 : || EDGE_SUCC (bb2, 0)->dest == EDGE_SUCC (bb2, 1)->dest)
6125 : 19929 : continue;
6126 : :
6127 : 88 : enum tree_code ccode2
6128 : 88 : = (operand_equal_p (gimple_cond_lhs (g), arg1, 0) ? LT_EXPR : GT_EXPR);
6129 : 88 : switch (gimple_cond_code (g))
6130 : : {
6131 : : case LT_EXPR:
6132 : : case LE_EXPR:
6133 : : break;
6134 : 39 : case GT_EXPR:
6135 : 39 : case GE_EXPR:
6136 : 39 : ccode2 = ccode2 == LT_EXPR ? GT_EXPR : LT_EXPR;
6137 : : break;
6138 : 0 : default:
6139 : 0 : continue;
6140 : : }
6141 : 88 : if (HONOR_NANS (TREE_TYPE (arg1)) && ccode == ccode2)
6142 : 0 : continue;
6143 : :
6144 : 176 : if ((ccode == LT_EXPR)
6145 : 88 : ^ ((EDGE_SUCC (bb1, i)->flags & EDGE_TRUE_VALUE) != 0))
6146 : : {
6147 : 39 : em1 = EDGE_SUCC (bb1, 1 - i);
6148 : 39 : e1 = EDGE_SUCC (bb2, 0);
6149 : 39 : e2 = EDGE_SUCC (bb2, 1);
6150 : 39 : if ((ccode2 == LT_EXPR) ^ ((e1->flags & EDGE_TRUE_VALUE) == 0))
6151 : 0 : std::swap (e1, e2);
6152 : : }
6153 : : else
6154 : : {
6155 : 49 : e1 = EDGE_SUCC (bb1, 1 - i);
6156 : 49 : em1 = EDGE_SUCC (bb2, 0);
6157 : 49 : e2 = EDGE_SUCC (bb2, 1);
6158 : 49 : if ((ccode2 != LT_EXPR) ^ ((em1->flags & EDGE_TRUE_VALUE) == 0))
6159 : : std::swap (em1, e2);
6160 : : }
6161 : : break;
6162 : : }
6163 : :
6164 : 10065 : if (em1 == NULL)
6165 : : {
6166 : 20052 : if ((ccode == LT_EXPR)
6167 : 10026 : ^ ((EDGE_SUCC (bb1, 0)->flags & EDGE_TRUE_VALUE) != 0))
6168 : : {
6169 : 3002 : em1 = EDGE_SUCC (bb1, 1);
6170 : 3002 : e1 = EDGE_SUCC (bb1, 0);
6171 : 3002 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6172 : : }
6173 : : else
6174 : : {
6175 : 7024 : em1 = EDGE_SUCC (bb1, 0);
6176 : 7024 : e1 = EDGE_SUCC (bb1, 1);
6177 : 7024 : e2 = (e1->flags & EDGE_TRUE_VALUE) ? em1 : e1;
6178 : : }
6179 : : }
6180 : :
6181 : : /* Check if there is a single bb into which all failed conditions
6182 : : jump to (perhaps through an empty block) and if it results in
6183 : : a single integral PHI which just sets it to -1, 0, 1, X
6184 : : (or -1, 0, 1 when NaNs can't happen). In that case use 1 rather
6185 : : than 0 as last .SPACESHIP argument to tell backends it might
6186 : : consider different code generation and just cast the result
6187 : : of .SPACESHIP to the PHI result. X above is some value
6188 : : other than -1, 0, 1, for libstdc++ 2, for libc++ -127. */
6189 : 10114 : tree arg3 = integer_zero_node;
6190 : 10114 : edge e = EDGE_SUCC (bb0, 0);
6191 : 10114 : if (e->dest == bb1)
6192 : 6572 : e = EDGE_SUCC (bb0, 1);
6193 : 10114 : basic_block bbp = e->dest;
6194 : 10114 : gphi *phi = NULL;
6195 : 10114 : for (gphi_iterator psi = gsi_start_phis (bbp);
6196 : 12196 : !gsi_end_p (psi); gsi_next (&psi))
6197 : : {
6198 : 3898 : gphi *gp = psi.phi ();
6199 : 3898 : tree res = gimple_phi_result (gp);
6200 : :
6201 : 3898 : if (phi != NULL
6202 : 3448 : || virtual_operand_p (res)
6203 : 2304 : || !INTEGRAL_TYPE_P (TREE_TYPE (res))
6204 : 6096 : || TYPE_PRECISION (TREE_TYPE (res)) < 2)
6205 : : {
6206 : : phi = NULL;
6207 : : break;
6208 : : }
6209 : 2082 : phi = gp;
6210 : : }
6211 : 10114 : if (phi
6212 : 1632 : && integer_zerop (gimple_phi_arg_def_from_edge (phi, e))
6213 : 10588 : && EDGE_COUNT (bbp->preds) == (HONOR_NANS (TREE_TYPE (arg1)) ? 4 : 3))
6214 : : {
6215 : 95 : HOST_WIDE_INT argval = SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) ? 2 : -1;
6216 : 566 : for (unsigned i = 0; phi && i < EDGE_COUNT (bbp->preds) - 1; ++i)
6217 : : {
6218 : 206 : edge e3 = i == 0 ? e1 : i == 1 ? em1 : e2;
6219 : 206 : if (e3->dest != bbp)
6220 : : {
6221 : 95 : if (!empty_block_p (e3->dest)
6222 : 85 : || !single_succ_p (e3->dest)
6223 : 180 : || single_succ (e3->dest) != bbp)
6224 : : {
6225 : : phi = NULL;
6226 : : break;
6227 : : }
6228 : : e3 = single_succ_edge (e3->dest);
6229 : : }
6230 : 196 : tree a = gimple_phi_arg_def_from_edge (phi, e3);
6231 : 196 : if (TREE_CODE (a) != INTEGER_CST
6232 : 196 : || (i == 0 && !integer_onep (a))
6233 : 388 : || (i == 1 && !integer_all_onesp (a)))
6234 : : {
6235 : : phi = NULL;
6236 : : break;
6237 : : }
6238 : 192 : if (i == 2)
6239 : : {
6240 : 30 : tree minv = TYPE_MIN_VALUE (signed_char_type_node);
6241 : 30 : tree maxv = TYPE_MAX_VALUE (signed_char_type_node);
6242 : 30 : widest_int w = widest_int::from (wi::to_wide (a), SIGNED);
6243 : 59 : if ((w >= -1 && w <= 1)
6244 : 26 : || w < wi::to_widest (minv)
6245 : 56 : || w > wi::to_widest (maxv))
6246 : : {
6247 : 4 : phi = NULL;
6248 : 4 : break;
6249 : : }
6250 : 26 : argval = w.to_shwi ();
6251 : 26 : }
6252 : : }
6253 : 95 : if (phi)
6254 : 77 : arg3 = build_int_cst (integer_type_node,
6255 : 89 : TYPE_UNSIGNED (TREE_TYPE (arg1)) ? 1 : argval);
6256 : : }
6257 : :
6258 : : /* For integral <=> comparisons only use .SPACESHIP if it is turned
6259 : : into an integer (-1, 0, 1). */
6260 : 10114 : if (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (arg1)) && arg3 == integer_zero_node)
6261 : : return;
6262 : :
6263 : 275 : gcall *gc = gimple_build_call_internal (IFN_SPACESHIP, 3, arg1, arg2, arg3);
6264 : 275 : tree lhs = make_ssa_name (integer_type_node);
6265 : 275 : gimple_call_set_lhs (gc, lhs);
6266 : 275 : gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
6267 : 275 : gsi_insert_before (&gsi, gc, GSI_SAME_STMT);
6268 : :
6269 : 473 : wide_int wmin = wi::minus_one (TYPE_PRECISION (integer_type_node));
6270 : 473 : wide_int wmax = wi::one (TYPE_PRECISION (integer_type_node));
6271 : 275 : if (HONOR_NANS (TREE_TYPE (arg1)))
6272 : : {
6273 : 205 : if (arg3 == integer_zero_node)
6274 : 179 : wmax = wi::two (TYPE_PRECISION (integer_type_node));
6275 : 26 : else if (tree_int_cst_sgn (arg3) < 0)
6276 : 1 : wmin = wi::to_wide (arg3);
6277 : : else
6278 : 25 : wmax = wi::to_wide (arg3);
6279 : : }
6280 : 473 : int_range<1> vr (TREE_TYPE (lhs), wmin, wmax);
6281 : 275 : set_range_info (lhs, vr);
6282 : :
6283 : 275 : if (arg3 != integer_zero_node)
6284 : : {
6285 : 77 : tree type = TREE_TYPE (gimple_phi_result (phi));
6286 : 77 : if (!useless_type_conversion_p (type, integer_type_node))
6287 : : {
6288 : 53 : tree tem = make_ssa_name (type);
6289 : 53 : gimple *gcv = gimple_build_assign (tem, NOP_EXPR, lhs);
6290 : 53 : gsi_insert_before (&gsi, gcv, GSI_SAME_STMT);
6291 : 53 : lhs = tem;
6292 : : }
6293 : 77 : SET_PHI_ARG_DEF_ON_EDGE (phi, e, lhs);
6294 : 77 : gimple_cond_set_lhs (stmt, boolean_false_node);
6295 : 77 : gimple_cond_set_rhs (stmt, boolean_false_node);
6296 : 141 : gimple_cond_set_code (stmt, (e->flags & EDGE_TRUE_VALUE)
6297 : : ? EQ_EXPR : NE_EXPR);
6298 : 77 : update_stmt (stmt);
6299 : 77 : return;
6300 : : }
6301 : :
6302 : 198 : gimple_cond_set_lhs (stmt, lhs);
6303 : 198 : gimple_cond_set_rhs (stmt, integer_zero_node);
6304 : 198 : update_stmt (stmt);
6305 : :
6306 : 396 : gcond *cond = as_a <gcond *> (*gsi_last_bb (bb1));
6307 : 198 : gimple_cond_set_lhs (cond, lhs);
6308 : 198 : if (em1->src == bb1 && e2 != em1)
6309 : : {
6310 : 105 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6311 : 111 : gimple_cond_set_code (cond, (em1->flags & EDGE_TRUE_VALUE)
6312 : : ? EQ_EXPR : NE_EXPR);
6313 : : }
6314 : : else
6315 : : {
6316 : 93 : gcc_assert (e1->src == bb1 && e2 != e1);
6317 : 93 : gimple_cond_set_rhs (cond, integer_one_node);
6318 : 93 : gimple_cond_set_code (cond, (e1->flags & EDGE_TRUE_VALUE)
6319 : : ? EQ_EXPR : NE_EXPR);
6320 : : }
6321 : 198 : update_stmt (cond);
6322 : :
6323 : 198 : if (e2 != e1 && e2 != em1)
6324 : : {
6325 : 124 : cond = as_a <gcond *> (*gsi_last_bb (bb2));
6326 : 62 : gimple_cond_set_lhs (cond, lhs);
6327 : 62 : if (em1->src == bb2)
6328 : 49 : gimple_cond_set_rhs (cond, integer_minus_one_node);
6329 : : else
6330 : : {
6331 : 13 : gcc_assert (e1->src == bb2);
6332 : 13 : gimple_cond_set_rhs (cond, integer_one_node);
6333 : : }
6334 : 62 : gimple_cond_set_code (cond,
6335 : 62 : (e2->flags & EDGE_TRUE_VALUE) ? NE_EXPR : EQ_EXPR);
6336 : 62 : update_stmt (cond);
6337 : : }
6338 : : }
6339 : :
6340 : :
6341 : : /* Find integer multiplications where the operands are extended from
6342 : : smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR
6343 : : or MULT_HIGHPART_EXPR where appropriate. */
6344 : :
6345 : : namespace {
6346 : :
6347 : : const pass_data pass_data_optimize_widening_mul =
6348 : : {
6349 : : GIMPLE_PASS, /* type */
6350 : : "widening_mul", /* name */
6351 : : OPTGROUP_NONE, /* optinfo_flags */
6352 : : TV_TREE_WIDEN_MUL, /* tv_id */
6353 : : PROP_ssa, /* properties_required */
6354 : : 0, /* properties_provided */
6355 : : 0, /* properties_destroyed */
6356 : : 0, /* todo_flags_start */
6357 : : TODO_update_ssa, /* todo_flags_finish */
6358 : : };
6359 : :
6360 : : class pass_optimize_widening_mul : public gimple_opt_pass
6361 : : {
6362 : : public:
6363 : 284673 : pass_optimize_widening_mul (gcc::context *ctxt)
6364 : 569346 : : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt)
6365 : : {}
6366 : :
6367 : : /* opt_pass methods: */
6368 : 1024172 : bool gate (function *) final override
6369 : : {
6370 : 1024172 : return flag_expensive_optimizations && optimize;
6371 : : }
6372 : :
6373 : : unsigned int execute (function *) final override;
6374 : :
6375 : : }; // class pass_optimize_widening_mul
6376 : :
6377 : : /* Walker class to perform the transformation in reverse dominance order. */
6378 : :
6379 : : class math_opts_dom_walker : public dom_walker
6380 : : {
6381 : : public:
6382 : : /* Constructor, CFG_CHANGED is a pointer to a boolean flag that will be set
6383 : : if walking modidifes the CFG. */
6384 : :
6385 : 950549 : math_opts_dom_walker (bool *cfg_changed_p)
6386 : 2851647 : : dom_walker (CDI_DOMINATORS), m_last_result_set (),
6387 : 950549 : m_cfg_changed_p (cfg_changed_p) {}
6388 : :
6389 : : /* The actual actions performed in the walk. */
6390 : :
6391 : : void after_dom_children (basic_block) final override;
6392 : :
6393 : : /* Set of results of chains of multiply and add statement combinations that
6394 : : were not transformed into FMAs because of active deferring. */
6395 : : hash_set<tree> m_last_result_set;
6396 : :
6397 : : /* Pointer to a flag of the user that needs to be set if CFG has been
6398 : : modified. */
6399 : : bool *m_cfg_changed_p;
6400 : : };
6401 : :
6402 : : void
6403 : 10452151 : math_opts_dom_walker::after_dom_children (basic_block bb)
6404 : : {
6405 : 10452151 : gimple_stmt_iterator gsi;
6406 : :
6407 : 10452151 : fma_deferring_state fma_state (param_avoid_fma_max_bits > 0);
6408 : :
6409 : 14893303 : for (gphi_iterator psi_next, psi = gsi_start_phis (bb); !gsi_end_p (psi);
6410 : 4441152 : psi = psi_next)
6411 : : {
6412 : 4441152 : psi_next = psi;
6413 : 4441152 : gsi_next (&psi_next);
6414 : :
6415 : 4441152 : gimple_stmt_iterator gsi = gsi_after_labels (bb);
6416 : 4441152 : gphi *phi = psi.phi ();
6417 : :
6418 : 4441152 : if (match_saturation_add (&gsi, phi)
6419 : 4441135 : || match_saturation_sub (&gsi, phi)
6420 : 8882277 : || match_saturation_trunc (&gsi, phi))
6421 : 27 : remove_phi_node (&psi, /* release_lhs_p */ false);
6422 : : }
6423 : :
6424 : 89999918 : for (gsi = gsi_after_labels (bb); !gsi_end_p (gsi);)
6425 : : {
6426 : 79547767 : gimple *stmt = gsi_stmt (gsi);
6427 : 79547767 : enum tree_code code;
6428 : :
6429 : 79547767 : if (is_gimple_assign (stmt))
6430 : : {
6431 : 21267784 : code = gimple_assign_rhs_code (stmt);
6432 : 21267784 : switch (code)
6433 : : {
6434 : 703639 : case MULT_EXPR:
6435 : 703639 : if (!convert_mult_to_widen (stmt, &gsi)
6436 : 693403 : && !convert_expand_mult_copysign (stmt, &gsi)
6437 : 1396996 : && convert_mult_to_fma (stmt,
6438 : : gimple_assign_rhs1 (stmt),
6439 : : gimple_assign_rhs2 (stmt),
6440 : : &fma_state))
6441 : : {
6442 : 17266 : gsi_remove (&gsi, true);
6443 : 17266 : release_defs (stmt);
6444 : 17266 : continue;
6445 : : }
6446 : 686373 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6447 : 686373 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6448 : 686373 : break;
6449 : :
6450 : 2217687 : case PLUS_EXPR:
6451 : 2217687 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6452 : 2217687 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6453 : : /* fall-through */
6454 : 2514966 : case MINUS_EXPR:
6455 : 2514966 : if (!convert_plusminus_to_widen (&gsi, stmt, code))
6456 : : {
6457 : 2514966 : match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p);
6458 : 2514966 : if (gsi_stmt (gsi) == stmt)
6459 : 2508587 : match_uaddc_usubc (&gsi, stmt, code);
6460 : : }
6461 : : break;
6462 : :
6463 : 35921 : case BIT_NOT_EXPR:
6464 : 35921 : if (match_arith_overflow (&gsi, stmt, code, m_cfg_changed_p))
6465 : 170 : continue;
6466 : : break;
6467 : :
6468 : 48503 : case TRUNC_MOD_EXPR:
6469 : 48503 : convert_to_divmod (as_a<gassign *> (stmt));
6470 : 48503 : break;
6471 : :
6472 : 169926 : case RSHIFT_EXPR:
6473 : 169926 : convert_mult_to_highpart (as_a<gassign *> (stmt), &gsi);
6474 : 169926 : break;
6475 : :
6476 : 191095 : case BIT_IOR_EXPR:
6477 : 191095 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6478 : 191095 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6479 : : /* fall-through */
6480 : 219844 : case BIT_XOR_EXPR:
6481 : 219844 : match_uaddc_usubc (&gsi, stmt, code);
6482 : 219844 : break;
6483 : :
6484 : 301431 : case EQ_EXPR:
6485 : 301431 : case NE_EXPR:
6486 : 301431 : case LE_EXPR:
6487 : 301431 : case GT_EXPR:
6488 : 301431 : match_single_bit_test (&gsi, stmt);
6489 : 301431 : break;
6490 : :
6491 : 362951 : case COND_EXPR:
6492 : 362951 : case BIT_AND_EXPR:
6493 : 362951 : match_unsigned_saturation_sub (&gsi, as_a<gassign *> (stmt));
6494 : 362951 : break;
6495 : :
6496 : 2372553 : case NOP_EXPR:
6497 : 2372553 : match_unsigned_saturation_mul (&gsi, as_a<gassign *> (stmt));
6498 : 2372553 : match_unsigned_saturation_trunc (&gsi, as_a<gassign *> (stmt));
6499 : 2372553 : match_saturation_add_with_assign (&gsi, as_a<gassign *> (stmt));
6500 : 2372553 : break;
6501 : :
6502 : : default:;
6503 : : }
6504 : : }
6505 : 58279983 : else if (is_gimple_call (stmt))
6506 : : {
6507 : 4712538 : switch (gimple_call_combined_fn (stmt))
6508 : : {
6509 : 474 : CASE_CFN_POW:
6510 : 474 : if (gimple_call_lhs (stmt)
6511 : 434 : && TREE_CODE (gimple_call_arg (stmt, 1)) == REAL_CST
6512 : 228 : && real_equal (&TREE_REAL_CST (gimple_call_arg (stmt, 1)),
6513 : : &dconst2)
6514 : 474 : && convert_mult_to_fma (stmt,
6515 : : gimple_call_arg (stmt, 0),
6516 : : gimple_call_arg (stmt, 0),
6517 : : &fma_state))
6518 : : {
6519 : 0 : unlink_stmt_vdef (stmt);
6520 : 0 : if (gsi_remove (&gsi, true)
6521 : 0 : && gimple_purge_dead_eh_edges (bb))
6522 : 0 : *m_cfg_changed_p = true;
6523 : 0 : release_defs (stmt);
6524 : 0 : continue;
6525 : : }
6526 : : break;
6527 : :
6528 : 129 : case CFN_COND_MUL:
6529 : 129 : if (convert_mult_to_fma (stmt,
6530 : : gimple_call_arg (stmt, 1),
6531 : : gimple_call_arg (stmt, 2),
6532 : : &fma_state,
6533 : : gimple_call_arg (stmt, 0)))
6534 : :
6535 : : {
6536 : 84 : gsi_remove (&gsi, true);
6537 : 84 : release_defs (stmt);
6538 : 84 : continue;
6539 : : }
6540 : : break;
6541 : :
6542 : 0 : case CFN_COND_LEN_MUL:
6543 : 0 : if (convert_mult_to_fma (stmt,
6544 : : gimple_call_arg (stmt, 1),
6545 : : gimple_call_arg (stmt, 2),
6546 : : &fma_state,
6547 : : gimple_call_arg (stmt, 0),
6548 : : gimple_call_arg (stmt, 4),
6549 : : gimple_call_arg (stmt, 5)))
6550 : :
6551 : : {
6552 : 0 : gsi_remove (&gsi, true);
6553 : 0 : release_defs (stmt);
6554 : 0 : continue;
6555 : : }
6556 : : break;
6557 : :
6558 : 3604314 : case CFN_LAST:
6559 : 3604314 : cancel_fma_deferring (&fma_state);
6560 : 3604314 : break;
6561 : :
6562 : : default:
6563 : : break;
6564 : : }
6565 : : }
6566 : 53567445 : else if (gimple_code (stmt) == GIMPLE_COND)
6567 : : {
6568 : 4101644 : match_single_bit_test (&gsi, stmt);
6569 : 4101644 : optimize_spaceship (as_a <gcond *> (stmt));
6570 : : }
6571 : 79530247 : gsi_next (&gsi);
6572 : : }
6573 : 10452151 : if (fma_state.m_deferring_p
6574 : 7721029 : && fma_state.m_initial_phi)
6575 : : {
6576 : 289 : gcc_checking_assert (fma_state.m_last_result);
6577 : 289 : if (!last_fma_candidate_feeds_initial_phi (&fma_state,
6578 : : &m_last_result_set))
6579 : 164 : cancel_fma_deferring (&fma_state);
6580 : : else
6581 : 125 : m_last_result_set.add (fma_state.m_last_result);
6582 : : }
6583 : 10452151 : }
6584 : :
6585 : :
6586 : : unsigned int
6587 : 950549 : pass_optimize_widening_mul::execute (function *fun)
6588 : : {
6589 : 950549 : bool cfg_changed = false;
6590 : :
6591 : 950549 : memset (&widen_mul_stats, 0, sizeof (widen_mul_stats));
6592 : 950549 : calculate_dominance_info (CDI_DOMINATORS);
6593 : 950549 : renumber_gimple_stmt_uids (cfun);
6594 : :
6595 : 950549 : math_opts_dom_walker (&cfg_changed).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
6596 : :
6597 : 950549 : statistics_counter_event (fun, "widening multiplications inserted",
6598 : : widen_mul_stats.widen_mults_inserted);
6599 : 950549 : statistics_counter_event (fun, "widening maccs inserted",
6600 : : widen_mul_stats.maccs_inserted);
6601 : 950549 : statistics_counter_event (fun, "fused multiply-adds inserted",
6602 : : widen_mul_stats.fmas_inserted);
6603 : 950549 : statistics_counter_event (fun, "divmod calls inserted",
6604 : : widen_mul_stats.divmod_calls_inserted);
6605 : 950549 : statistics_counter_event (fun, "highpart multiplications inserted",
6606 : : widen_mul_stats.highpart_mults_inserted);
6607 : :
6608 : 950549 : return cfg_changed ? TODO_cleanup_cfg : 0;
6609 : : }
6610 : :
6611 : : } // anon namespace
6612 : :
6613 : : gimple_opt_pass *
6614 : 284673 : make_pass_optimize_widening_mul (gcc::context *ctxt)
6615 : : {
6616 : 284673 : return new pass_optimize_widening_mul (ctxt);
6617 : : }
|