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