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