1 /* Helpers for the autogenerated gimple-match.cc file.
2 Copyright (C) 2023-2025 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free
8 Software Foundation; either version 3, or (at your option) any later
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
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/>. */
22 #include "coretypes.h"
30 #include "vec-perm-indices.h"
31 #include "fold-const.h"
32 #include "fold-const-call.h"
33 #include "stor-layout.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
39 #include "gimple-match.h"
40 #include "tree-pass.h"
41 #include "internal-fn.h"
42 #include "case-cfn-macros.h"
44 #include "optabs-tree.h"
48 #include "gimple-range.h"
49 #include "langhooks.h"
51 tree (*mprts_hook
) (gimple_match_op
*);
53 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
54 code_helper
, tree
, tree
);
55 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
56 code_helper
, tree
, tree
, tree
);
57 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
58 code_helper
, tree
, tree
, tree
, tree
);
59 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
60 code_helper
, tree
, tree
, tree
, tree
, tree
);
61 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
62 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
);
63 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
64 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
,
66 extern bool gimple_simplify (gimple_match_op
*, gimple_seq
*, tree (*)(tree
),
67 code_helper
, tree
, tree
, tree
, tree
, tree
, tree
,
70 /* Functions that are needed by gimple-match but that are exported and used in
71 other places in the compiler. */
73 tree
gimple_simplify (enum tree_code
, tree
, tree
, gimple_seq
*,
75 tree
gimple_simplify (enum tree_code
, tree
, tree
, tree
, gimple_seq
*,
77 tree
gimple_simplify (enum tree_code
, tree
, tree
, tree
, tree
, gimple_seq
*,
79 tree
gimple_simplify (combined_fn
, tree
, tree
, gimple_seq
*,
81 tree
gimple_simplify (combined_fn
, tree
, tree
, tree
, gimple_seq
*,
83 tree
gimple_simplify (combined_fn
, tree
, tree
, tree
, tree
, gimple_seq
*,
86 tree
do_valueize (tree
, tree (*)(tree
), bool &);
87 tree
do_valueize (tree (*)(tree
), tree
);
89 /* Forward declarations of the private auto-generated matchers.
90 They expect valueized operands in canonical order and do not
91 perform simplification of all-constant operands. */
93 static bool gimple_resimplify1 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
94 static bool gimple_resimplify2 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
95 static bool gimple_resimplify3 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
96 static bool gimple_resimplify4 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
97 static bool gimple_resimplify5 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
98 static bool gimple_resimplify6 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
99 static bool gimple_resimplify7 (gimple_seq
*, gimple_match_op
*, tree (*)(tree
));
101 /* Match and simplify the toplevel valueized operation THIS.
102 Replaces THIS with a simplified and/or canonicalized result and
103 returns whether any change was made. */
106 gimple_match_op::resimplify (gimple_seq
*seq
, tree (*valueize
)(tree
))
111 return gimple_resimplify1 (seq
, this, valueize
);
113 return gimple_resimplify2 (seq
, this, valueize
);
115 return gimple_resimplify3 (seq
, this, valueize
);
117 return gimple_resimplify4 (seq
, this, valueize
);
119 return gimple_resimplify5 (seq
, this, valueize
);
121 return gimple_resimplify6 (seq
, this, valueize
);
123 return gimple_resimplify7 (seq
, this, valueize
);
129 /* Returns true if any of the operands of THIS occurs
132 gimple_match_op::operands_occurs_in_abnormal_phi() const
134 for (unsigned int i
= 0; i
< num_ops
; i
++)
136 if (TREE_CODE (ops
[i
]) == SSA_NAME
137 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[i
]))
143 /* Return whether T is a constant that we'll dispatch to fold to
144 evaluate fully constant expressions. */
147 constant_for_folding (tree t
)
149 return (CONSTANT_CLASS_P (t
)
150 /* The following is only interesting to string builtins. */
151 || (TREE_CODE (t
) == ADDR_EXPR
152 && TREE_CODE (TREE_OPERAND (t
, 0)) == STRING_CST
));
155 /* Try to convert conditional operation ORIG_OP into an IFN_COND_*
156 operation. Return true on success, storing the new operation in NEW_OP. */
159 convert_conditional_op (gimple_match_op
*orig_op
,
160 gimple_match_op
*new_op
)
163 if (orig_op
->code
.is_tree_code ())
164 ifn
= get_conditional_internal_fn ((tree_code
) orig_op
->code
);
167 auto cfn
= combined_fn (orig_op
->code
);
168 if (!internal_fn_p (cfn
))
170 ifn
= get_conditional_internal_fn (as_internal_fn (cfn
));
174 unsigned int num_ops
= orig_op
->num_ops
;
175 unsigned int num_cond_ops
= 2;
176 if (orig_op
->cond
.len
)
178 /* Add the length and bias parameters. */
179 ifn
= get_len_internal_fn (ifn
);
182 new_op
->set_op (as_combined_fn (ifn
), orig_op
->type
, num_ops
+ num_cond_ops
);
183 new_op
->ops
[0] = orig_op
->cond
.cond
;
184 for (unsigned int i
= 0; i
< num_ops
; ++i
)
185 new_op
->ops
[i
+ 1] = orig_op
->ops
[i
];
186 tree else_value
= orig_op
->cond
.else_value
;
188 else_value
= targetm
.preferred_else_value (ifn
, orig_op
->type
,
189 num_ops
, orig_op
->ops
);
190 new_op
->ops
[num_ops
+ 1] = else_value
;
191 if (orig_op
->cond
.len
)
193 new_op
->ops
[num_ops
+ 2] = orig_op
->cond
.len
;
194 new_op
->ops
[num_ops
+ 3] = orig_op
->cond
.bias
;
198 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting
199 VALUEIZED to true if valueization changed OP. */
202 do_valueize (tree op
, tree (*valueize
)(tree
), bool &valueized
)
204 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
206 tree tem
= valueize (op
);
207 if (tem
&& tem
!= op
)
216 /* If in GIMPLE the operation described by RES_OP should be single-rhs,
217 build a GENERIC tree for that expression and update RES_OP accordingly. */
220 maybe_build_generic_op (gimple_match_op
*res_op
)
222 tree_code code
= (tree_code
) res_op
->code
;
228 case VIEW_CONVERT_EXPR
:
229 val
= build1 (code
, res_op
->type
, res_op
->ops
[0]);
230 res_op
->set_value (val
);
233 val
= build3 (code
, res_op
->type
, res_op
->ops
[0], res_op
->ops
[1],
235 REF_REVERSE_STORAGE_ORDER (val
) = res_op
->reverse
;
236 res_op
->set_value (val
);
242 /* Try to build RES_OP, which is known to be a call to FN. Return null
243 if the target doesn't support the function. */
246 build_call_internal (internal_fn fn
, gimple_match_op
*res_op
)
248 if (direct_internal_fn_p (fn
))
250 tree_pair types
= direct_internal_fn_types (fn
, res_op
->type
,
252 if (!direct_internal_fn_supported_p (fn
, types
, OPTIMIZE_FOR_BOTH
))
262 /* For these 6 builtins large/huge _BitInt operand is ok
263 before bitint lowering pass. */
264 if (res_op
->num_ops
>= 1
265 && TREE_CODE (TREE_TYPE (res_op
->ops
[0])) == BITINT_TYPE
266 && (TYPE_PRECISION (TREE_TYPE (res_op
->ops
[0]))
267 > MAX_FIXED_MODE_SIZE
)
269 && (cfun
->curr_properties
& PROP_gimple_lbitint
) == 0)
278 return gimple_build_call_internal (fn
, res_op
->num_ops
,
279 res_op
->op_or_null (0),
280 res_op
->op_or_null (1),
281 res_op
->op_or_null (2),
282 res_op
->op_or_null (3),
283 res_op
->op_or_null (4),
284 res_op
->op_or_null (5),
285 res_op
->op_or_null (6));
288 /* RES_OP is the result of a simplification. If it is conditional,
289 try to replace it with the equivalent UNCOND form, such as an
290 IFN_COND_* call or a VEC_COND_EXPR. Also try to resimplify the
291 result of the replacement if appropriate, adding any new statements to
292 SEQ and using VALUEIZE as the valueization function. Return true if
293 this resimplification occurred and resulted in at least one change. */
296 maybe_resimplify_conditional_op (gimple_seq
*seq
, gimple_match_op
*res_op
,
297 tree (*valueize
) (tree
))
299 if (!res_op
->cond
.cond
)
302 if (!res_op
->cond
.else_value
303 && res_op
->code
.is_tree_code ())
305 /* The "else" value doesn't matter. If the "then" value is a
306 gimple value, just use it unconditionally. This isn't a
307 simplification in itself, since there was no operation to
308 build in the first place. */
309 if (gimple_simplified_result_is_gimple_val (res_op
))
311 res_op
->cond
.cond
= NULL_TREE
;
315 /* Likewise if the operation would not trap. */
316 bool honor_trapv
= (INTEGRAL_TYPE_P (res_op
->type
)
317 && TYPE_OVERFLOW_TRAPS (res_op
->type
));
318 tree_code op_code
= (tree_code
) res_op
->code
;
321 /* COND_EXPR will trap if, and only if, the condition
322 traps and hence we have to check this. For all other operations, we
323 don't need to consider the operands. */
324 if (op_code
== COND_EXPR
)
325 op_could_trap
= generic_expr_could_trap_p (res_op
->ops
[0]);
327 op_could_trap
= operation_could_trap_p ((tree_code
) res_op
->code
,
328 FLOAT_TYPE_P (res_op
->type
),
330 res_op
->op_or_null (1));
334 res_op
->cond
.cond
= NULL_TREE
;
339 /* If the "then" value is a gimple value and the "else" value matters,
340 create a (VEC_)COND_EXPR between them, then see if it can be further
342 gimple_match_op new_op
;
343 if (res_op
->cond
.else_value
344 && gimple_simplified_result_is_gimple_val (res_op
))
346 if (VECTOR_TYPE_P (res_op
->type
))
348 tree len
= res_op
->cond
.len
;
350 new_op
.set_op (VEC_COND_EXPR
, res_op
->type
,
351 res_op
->cond
.cond
, res_op
->ops
[0],
352 res_op
->cond
.else_value
);
354 new_op
.set_op (IFN_VCOND_MASK_LEN
, res_op
->type
,
355 res_op
->cond
.cond
, res_op
->ops
[0],
356 res_op
->cond
.else_value
,
357 res_op
->cond
.len
, res_op
->cond
.bias
);
360 new_op
.set_op (COND_EXPR
, res_op
->type
,
361 res_op
->cond
.cond
, res_op
->ops
[0],
362 res_op
->cond
.else_value
);
364 return gimple_resimplify3 (seq
, res_op
, valueize
);
367 /* Otherwise try rewriting the operation as an IFN_COND_* call.
368 Again, this isn't a simplification in itself, since it's what
369 RES_OP already described. */
370 if (convert_conditional_op (res_op
, &new_op
))
376 /* If RES_OP is a call to a conditional internal function, try simplifying
377 the associated unconditional operation and using the result to build
378 a new conditional operation. For example, if RES_OP is:
380 IFN_COND_ADD (COND, A, B, ELSE)
382 try simplifying (plus A B) and using the result to build a replacement
383 for the whole IFN_COND_ADD.
385 Return true if this approach led to a simplification, otherwise leave
386 RES_OP unchanged (and so suitable for other simplifications). When
387 returning true, add any new statements to SEQ and use VALUEIZE as the
388 valueization function.
390 RES_OP is known to be a call to IFN. */
393 try_conditional_simplification (internal_fn ifn
, gimple_match_op
*res_op
,
394 gimple_seq
*seq
, tree (*valueize
) (tree
))
397 tree_code code
= conditional_internal_fn_code (ifn
);
398 int len_index
= internal_fn_len_index (ifn
);
399 if (code
!= ERROR_MARK
)
403 ifn
= get_unconditional_internal_fn (ifn
);
406 op
= as_combined_fn (ifn
);
409 unsigned int num_ops
= res_op
->num_ops
;
410 /* num_cond_ops = 2 for COND_ADD (MASK and ELSE)
411 wheras num_cond_ops = 4 for COND_LEN_ADD (MASK, ELSE, LEN and BIAS). */
412 unsigned int num_cond_ops
= len_index
< 0 ? 2 : 4;
414 = len_index
< 0 ? res_op
->ops
[num_ops
- 1] : res_op
->ops
[num_ops
- 3];
415 tree len
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 2];
416 tree bias
= len_index
< 0 ? NULL_TREE
: res_op
->ops
[num_ops
- 1];
417 gimple_match_op
cond_op (gimple_match_cond (res_op
->ops
[0],
418 else_value
, len
, bias
),
419 op
, res_op
->type
, num_ops
- num_cond_ops
);
421 memcpy (cond_op
.ops
, res_op
->ops
+ 1, (num_ops
- 1) * sizeof *cond_op
.ops
);
422 switch (num_ops
- num_cond_ops
)
425 if (!gimple_resimplify1 (seq
, &cond_op
, valueize
))
429 if (!gimple_resimplify2 (seq
, &cond_op
, valueize
))
433 if (!gimple_resimplify3 (seq
, &cond_op
, valueize
))
440 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
444 /* Helper for the autogenerated code, valueize OP. */
447 do_valueize (tree (*valueize
)(tree
), tree op
)
449 if (valueize
&& TREE_CODE (op
) == SSA_NAME
)
451 tree tem
= valueize (op
);
458 /* Push the exploded expression described by RES_OP as a statement to
459 SEQ if necessary and return a gimple value denoting the value of the
460 expression. If RES is not NULL then the result will be always RES
461 and even gimple values are pushed to SEQ. */
464 maybe_push_res_to_seq (gimple_match_op
*res_op
, gimple_seq
*seq
, tree res
)
466 tree
*ops
= res_op
->ops
;
467 unsigned num_ops
= res_op
->num_ops
;
469 /* The caller should have converted conditional operations into an UNCOND
470 form and resimplified as appropriate. The conditional form only
471 survives this far if that conversion failed. */
472 if (res_op
->cond
.cond
)
475 if (res_op
->code
.is_tree_code ())
478 && gimple_simplified_result_is_gimple_val (res_op
))
482 tree tem
= mprts_hook (res_op
);
491 /* Play safe and do not allow abnormals to be mentioned in
492 newly created statements. */
493 for (unsigned int i
= 0; i
< num_ops
; ++i
)
494 if (TREE_CODE (ops
[i
]) == SSA_NAME
495 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops
[i
]))
498 if (res_op
->code
.is_tree_code ())
500 auto code
= tree_code (res_op
->code
);
503 if (gimple_in_ssa_p (cfun
))
504 res
= make_ssa_name (res_op
->type
);
506 res
= create_tmp_reg (res_op
->type
);
508 maybe_build_generic_op (res_op
);
509 gimple
*new_stmt
= gimple_build_assign (res
, code
,
510 res_op
->op_or_null (0),
511 res_op
->op_or_null (1),
512 res_op
->op_or_null (2));
513 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
518 gcc_assert (num_ops
!= 0);
519 auto fn
= combined_fn (res_op
->code
);
520 gcall
*new_stmt
= NULL
;
521 if (internal_fn_p (fn
))
523 /* Generate the given function if we can. */
524 internal_fn ifn
= as_internal_fn (fn
);
526 /* We can't and should not emit calls to non-const functions. */
527 if (!(internal_fn_flags (ifn
) & ECF_CONST
))
530 new_stmt
= build_call_internal (ifn
, res_op
);
536 /* Find the function we want to call. */
537 tree decl
= builtin_decl_implicit (as_builtin_fn (fn
));
541 /* We can't and should not emit calls to non-const functions. */
542 if (!(flags_from_decl_or_type (decl
) & ECF_CONST
))
545 new_stmt
= gimple_build_call (decl
, num_ops
,
546 res_op
->op_or_null (0),
547 res_op
->op_or_null (1),
548 res_op
->op_or_null (2),
549 res_op
->op_or_null (3),
550 res_op
->op_or_null (4));
554 if (gimple_in_ssa_p (cfun
))
555 res
= make_ssa_name (res_op
->type
);
557 res
= create_tmp_reg (res_op
->type
);
559 gimple_call_set_lhs (new_stmt
, res
);
560 gimple_seq_add_stmt_without_update (seq
, new_stmt
);
566 /* Public API overloads follow for operation being tree_code or
567 built_in_function and for one to three operands or arguments.
568 They return NULL_TREE if nothing could be simplified or
569 the resulting simplified value with parts pushed to SEQ.
570 If SEQ is NULL then if the simplification needs to create
571 new stmts it will fail. If VALUEIZE is non-NULL then all
572 SSA names will be valueized using that hook prior to
573 applying simplifications. */
578 gimple_simplify (enum tree_code code
, tree type
,
580 gimple_seq
*seq
, tree (*valueize
)(tree
))
582 if (constant_for_folding (op0
))
584 tree res
= const_unop (code
, type
, op0
);
586 && CONSTANT_CLASS_P (res
))
590 gimple_match_op res_op
;
591 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
))
593 return maybe_push_res_to_seq (&res_op
, seq
);
599 gimple_simplify (enum tree_code code
, tree type
,
601 gimple_seq
*seq
, tree (*valueize
)(tree
))
603 if (constant_for_folding (op0
) && constant_for_folding (op1
))
605 tree res
= const_binop (code
, type
, op0
, op1
);
607 && CONSTANT_CLASS_P (res
))
611 /* Canonicalize operand order both for matching and fallback stmt
613 if ((commutative_tree_code (code
)
614 || TREE_CODE_CLASS (code
) == tcc_comparison
)
615 && tree_swap_operands_p (op0
, op1
))
617 std::swap (op0
, op1
);
618 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
619 code
= swap_tree_comparison (code
);
622 gimple_match_op res_op
;
623 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
))
625 return maybe_push_res_to_seq (&res_op
, seq
);
631 gimple_simplify (enum tree_code code
, tree type
,
632 tree op0
, tree op1
, tree op2
,
633 gimple_seq
*seq
, tree (*valueize
)(tree
))
635 if (constant_for_folding (op0
) && constant_for_folding (op1
)
636 && constant_for_folding (op2
))
638 tree res
= fold_ternary
/*_to_constant */ (code
, type
, op0
, op1
, op2
);
640 && CONSTANT_CLASS_P (res
))
644 /* Canonicalize operand order both for matching and fallback stmt
646 if (commutative_ternary_tree_code (code
)
647 && tree_swap_operands_p (op0
, op1
))
648 std::swap (op0
, op1
);
650 gimple_match_op res_op
;
651 if (!gimple_simplify (&res_op
, seq
, valueize
, code
, type
, op0
, op1
, op2
))
653 return maybe_push_res_to_seq (&res_op
, seq
);
656 /* Builtin or internal function with one argument. */
659 gimple_simplify (combined_fn fn
, tree type
,
661 gimple_seq
*seq
, tree (*valueize
)(tree
))
663 if (constant_for_folding (arg0
))
665 tree res
= fold_const_call (fn
, type
, arg0
);
666 if (res
&& CONSTANT_CLASS_P (res
))
670 gimple_match_op res_op
;
671 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
))
673 return maybe_push_res_to_seq (&res_op
, seq
);
676 /* Builtin or internal function with two arguments. */
679 gimple_simplify (combined_fn fn
, tree type
,
680 tree arg0
, tree arg1
,
681 gimple_seq
*seq
, tree (*valueize
)(tree
))
683 if (constant_for_folding (arg0
)
684 && constant_for_folding (arg1
))
686 tree res
= fold_const_call (fn
, type
, arg0
, arg1
);
687 if (res
&& CONSTANT_CLASS_P (res
))
691 gimple_match_op res_op
;
692 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
))
694 return maybe_push_res_to_seq (&res_op
, seq
);
697 /* Builtin or internal function with three arguments. */
700 gimple_simplify (combined_fn fn
, tree type
,
701 tree arg0
, tree arg1
, tree arg2
,
702 gimple_seq
*seq
, tree (*valueize
)(tree
))
704 if (constant_for_folding (arg0
)
705 && constant_for_folding (arg1
)
706 && constant_for_folding (arg2
))
708 tree res
= fold_const_call (fn
, type
, arg0
, arg1
, arg2
);
709 if (res
&& CONSTANT_CLASS_P (res
))
713 gimple_match_op res_op
;
714 if (!gimple_simplify (&res_op
, seq
, valueize
, fn
, type
, arg0
, arg1
, arg2
))
716 return maybe_push_res_to_seq (&res_op
, seq
);
719 /* Common subroutine of gimple_extract_op and gimple_simplify. Try to
720 describe STMT in RES_OP, returning true on success. Before recording
723 - VALUEIZE_CONDITION for a COND_EXPR condition
724 - VALUEIZE_OP for every other top-level operand
726 Both routines take a tree argument and returns a tree. */
728 template<typename ValueizeOp
, typename ValueizeCondition
>
730 gimple_extract (gimple
*stmt
, gimple_match_op
*res_op
,
731 ValueizeOp valueize_op
,
732 ValueizeCondition valueize_condition
)
734 switch (gimple_code (stmt
))
738 enum tree_code code
= gimple_assign_rhs_code (stmt
);
739 tree type
= TREE_TYPE (gimple_assign_lhs (stmt
));
740 switch (gimple_assign_rhs_class (stmt
))
742 case GIMPLE_SINGLE_RHS
:
743 if (code
== REALPART_EXPR
744 || code
== IMAGPART_EXPR
745 || code
== VIEW_CONVERT_EXPR
)
747 tree op0
= TREE_OPERAND (gimple_assign_rhs1 (stmt
), 0);
748 /* op0 needs to be a SSA name or an min invariant. */
749 if (TREE_CODE (op0
) != SSA_NAME
&& !is_gimple_min_invariant (op0
))
751 res_op
->set_op (code
, type
, valueize_op (op0
));
754 else if (code
== BIT_FIELD_REF
)
756 tree rhs1
= gimple_assign_rhs1 (stmt
);
757 tree op0
= valueize_op (TREE_OPERAND (rhs1
, 0));
758 /* op0 needs to be a SSA name or an min invariant. */
759 if (TREE_CODE (op0
) != SSA_NAME
&& !is_gimple_min_invariant (op0
))
761 res_op
->set_op (code
, type
, op0
,
762 TREE_OPERAND (rhs1
, 1),
763 TREE_OPERAND (rhs1
, 2),
764 REF_REVERSE_STORAGE_ORDER (rhs1
));
767 else if (code
== SSA_NAME
)
769 tree op0
= gimple_assign_rhs1 (stmt
);
770 res_op
->set_op (TREE_CODE (op0
), type
, valueize_op (op0
));
774 case GIMPLE_UNARY_RHS
:
776 tree rhs1
= gimple_assign_rhs1 (stmt
);
777 res_op
->set_op (code
, type
, valueize_op (rhs1
));
780 case GIMPLE_BINARY_RHS
:
782 tree rhs1
= valueize_op (gimple_assign_rhs1 (stmt
));
783 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
784 res_op
->set_op (code
, type
, rhs1
, rhs2
);
787 case GIMPLE_TERNARY_RHS
:
789 tree rhs1
= valueize_op (gimple_assign_rhs1 (stmt
));
790 tree rhs2
= valueize_op (gimple_assign_rhs2 (stmt
));
791 tree rhs3
= valueize_op (gimple_assign_rhs3 (stmt
));
792 res_op
->set_op (code
, type
, rhs1
, rhs2
, rhs3
);
802 /* ??? This way we can't simplify calls with side-effects. */
803 if (gimple_call_lhs (stmt
) != NULL_TREE
804 && gimple_call_num_args (stmt
) >= 1
805 && gimple_call_num_args (stmt
) <= 7)
808 if (gimple_call_internal_p (stmt
))
809 cfn
= as_combined_fn (gimple_call_internal_fn (stmt
));
812 tree fn
= gimple_call_fn (stmt
);
816 fn
= valueize_op (fn
);
817 if (TREE_CODE (fn
) != ADDR_EXPR
818 || TREE_CODE (TREE_OPERAND (fn
, 0)) != FUNCTION_DECL
)
821 tree decl
= TREE_OPERAND (fn
, 0);
822 if (DECL_BUILT_IN_CLASS (decl
) != BUILT_IN_NORMAL
823 || !gimple_builtin_call_types_compatible_p (stmt
, decl
))
826 cfn
= as_combined_fn (DECL_FUNCTION_CODE (decl
));
829 unsigned int num_args
= gimple_call_num_args (stmt
);
830 res_op
->set_op (cfn
, TREE_TYPE (gimple_call_lhs (stmt
)), num_args
);
831 for (unsigned i
= 0; i
< num_args
; ++i
)
832 res_op
->ops
[i
] = valueize_op (gimple_call_arg (stmt
, i
));
839 tree lhs
= valueize_op (gimple_cond_lhs (stmt
));
840 tree rhs
= valueize_op (gimple_cond_rhs (stmt
));
841 res_op
->set_op (gimple_cond_code (stmt
), boolean_type_node
, lhs
, rhs
);
852 /* Try to describe STMT in RES_OP, returning true on success.
853 For GIMPLE_CONDs, describe the condition that is being tested.
854 For GIMPLE_ASSIGNs, describe the rhs of the assignment.
855 For GIMPLE_CALLs, describe the call. */
858 gimple_extract_op (gimple
*stmt
, gimple_match_op
*res_op
)
860 auto nop
= [](tree op
) { return op
; };
861 return gimple_extract (stmt
, res_op
, nop
, nop
);
864 /* The main STMT based simplification entry. It is used by the fold_stmt
865 and the fold_stmt_to_constant APIs. */
868 gimple_simplify (gimple
*stmt
, gimple_match_op
*res_op
, gimple_seq
*seq
,
869 tree (*valueize
)(tree
), tree (*top_valueize
)(tree
))
871 bool valueized
= false;
872 auto valueize_op
= [&](tree op
)
874 return do_valueize (op
, top_valueize
, valueized
);
876 auto valueize_condition
= [&](tree op
) -> tree
878 bool cond_valueized
= false;
879 tree lhs
= do_valueize (TREE_OPERAND (op
, 0), top_valueize
,
881 tree rhs
= do_valueize (TREE_OPERAND (op
, 1), top_valueize
,
883 gimple_match_op
res_op2 (res_op
->cond
, TREE_CODE (op
),
884 TREE_TYPE (op
), lhs
, rhs
);
885 if ((gimple_resimplify2 (seq
, &res_op2
, valueize
)
887 && res_op2
.code
.is_tree_code ())
889 auto code
= tree_code (res_op2
.code
);
890 if (TREE_CODE_CLASS (code
) == tcc_comparison
)
893 return build2 (code
, TREE_TYPE (op
),
894 res_op2
.ops
[0], res_op2
.ops
[1]);
896 else if (code
== SSA_NAME
897 || code
== INTEGER_CST
898 || code
== VECTOR_CST
)
901 return res_op2
.ops
[0];
904 return valueize_op (op
);
907 if (!gimple_extract (stmt
, res_op
, valueize_op
, valueize_condition
))
910 if (res_op
->code
.is_internal_fn ())
912 internal_fn ifn
= internal_fn (res_op
->code
);
913 if (try_conditional_simplification (ifn
, res_op
, seq
, valueize
))
919 && res_op
->resimplify (seq
, valueize
))
925 /* Helper that matches and simplifies the toplevel result from
926 a gimple_simplify run (where we don't want to build
927 a stmt in case it's used in in-place folding). Replaces
928 RES_OP with a simplified and/or canonicalized result and
929 returns whether any change was made. */
932 gimple_resimplify1 (gimple_seq
*seq
, gimple_match_op
*res_op
,
933 tree (*valueize
)(tree
))
935 if (constant_for_folding (res_op
->ops
[0]))
937 tree tem
= NULL_TREE
;
938 if (res_op
->code
.is_tree_code ())
940 auto code
= tree_code (res_op
->code
);
941 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
942 && TREE_CODE_LENGTH (code
) == 1)
943 tem
= const_unop (code
, res_op
->type
, res_op
->ops
[0]);
946 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
949 && CONSTANT_CLASS_P (tem
))
951 if (TREE_OVERFLOW_P (tem
))
952 tem
= drop_tree_overflow (tem
);
953 res_op
->set_value (tem
);
954 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
959 /* Limit recursion, there are cases like PR80887 and others, for
960 example when value-numbering presents us with unfolded expressions
961 that we are really not prepared to handle without eventual
962 oscillation like ((_50 + 0) + 8) where _50 gets mapped to _50
963 itself as available expression. */
964 static unsigned depth
;
967 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
968 fprintf (dump_file
, "Aborting expression simplification due to "
974 gimple_match_op
res_op2 (*res_op
);
975 if (gimple_simplify (&res_op2
, seq
, valueize
,
976 res_op
->code
, res_op
->type
, res_op
->ops
[0]))
984 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
990 /* Helper that matches and simplifies the toplevel result from
991 a gimple_simplify run (where we don't want to build
992 a stmt in case it's used in in-place folding). Replaces
993 RES_OP with a simplified and/or canonicalized result and
994 returns whether any change was made. */
997 gimple_resimplify2 (gimple_seq
*seq
, gimple_match_op
*res_op
,
998 tree (*valueize
)(tree
))
1000 if (constant_for_folding (res_op
->ops
[0])
1001 && constant_for_folding (res_op
->ops
[1]))
1003 tree tem
= NULL_TREE
;
1004 if (res_op
->code
.is_tree_code ())
1006 auto code
= tree_code (res_op
->code
);
1007 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
1008 && TREE_CODE_LENGTH (code
) == 2)
1009 tem
= const_binop (code
, res_op
->type
,
1010 res_op
->ops
[0], res_op
->ops
[1]);
1013 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
1014 res_op
->ops
[0], res_op
->ops
[1]);
1015 if (tem
!= NULL_TREE
1016 && CONSTANT_CLASS_P (tem
))
1018 if (TREE_OVERFLOW_P (tem
))
1019 tem
= drop_tree_overflow (tem
);
1020 res_op
->set_value (tem
);
1021 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
1026 /* Canonicalize operand order. */
1027 bool canonicalized
= false;
1029 = (res_op
->code
.is_tree_code ()
1030 && TREE_CODE_CLASS (tree_code (res_op
->code
)) == tcc_comparison
);
1031 if ((is_comparison
|| commutative_binary_op_p (res_op
->code
, res_op
->type
))
1032 && tree_swap_operands_p (res_op
->ops
[0], res_op
->ops
[1]))
1034 std::swap (res_op
->ops
[0], res_op
->ops
[1]);
1036 res_op
->code
= swap_tree_comparison (tree_code (res_op
->code
));
1037 canonicalized
= true;
1040 /* Limit recursion, see gimple_resimplify1. */
1041 static unsigned depth
;
1044 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1045 fprintf (dump_file
, "Aborting expression simplification due to "
1046 "deep recursion\n");
1051 gimple_match_op
res_op2 (*res_op
);
1052 if (gimple_simplify (&res_op2
, seq
, valueize
,
1053 res_op
->code
, res_op
->type
,
1054 res_op
->ops
[0], res_op
->ops
[1]))
1062 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1065 return canonicalized
;
1068 /* Helper that matches and simplifies the toplevel result from
1069 a gimple_simplify run (where we don't want to build
1070 a stmt in case it's used in in-place folding). Replaces
1071 RES_OP with a simplified and/or canonicalized result and
1072 returns whether any change was made. */
1075 gimple_resimplify3 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1076 tree (*valueize
)(tree
))
1078 if (constant_for_folding (res_op
->ops
[0])
1079 && constant_for_folding (res_op
->ops
[1])
1080 && constant_for_folding (res_op
->ops
[2]))
1082 tree tem
= NULL_TREE
;
1083 if (res_op
->code
.is_tree_code ())
1085 auto code
= tree_code (res_op
->code
);
1086 if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code
))
1087 && TREE_CODE_LENGTH (code
) == 3)
1088 tem
= fold_ternary
/*_to_constant*/ (code
, res_op
->type
,
1089 res_op
->ops
[0], res_op
->ops
[1],
1093 tem
= fold_const_call (combined_fn (res_op
->code
), res_op
->type
,
1094 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]);
1095 if (tem
!= NULL_TREE
1096 && CONSTANT_CLASS_P (tem
))
1098 if (TREE_OVERFLOW_P (tem
))
1099 tem
= drop_tree_overflow (tem
);
1100 res_op
->set_value (tem
);
1101 maybe_resimplify_conditional_op (seq
, res_op
, valueize
);
1106 /* Canonicalize operand order. */
1107 bool canonicalized
= false;
1108 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1110 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1112 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1113 canonicalized
= true;
1116 /* Limit recursion, see gimple_resimplify1. */
1117 static unsigned depth
;
1120 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1121 fprintf (dump_file
, "Aborting expression simplification due to "
1122 "deep recursion\n");
1127 gimple_match_op
res_op2 (*res_op
);
1128 if (gimple_simplify (&res_op2
, seq
, valueize
,
1129 res_op
->code
, res_op
->type
,
1130 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2]))
1138 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1141 return canonicalized
;
1144 /* Helper that matches and simplifies the toplevel result from
1145 a gimple_simplify run (where we don't want to build
1146 a stmt in case it's used in in-place folding). Replaces
1147 RES_OP with a simplified and/or canonicalized result and
1148 returns whether any change was made. */
1151 gimple_resimplify4 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1152 tree (*valueize
)(tree
))
1154 /* No constant folding is defined for four-operand functions. */
1156 /* Canonicalize operand order. */
1157 bool canonicalized
= false;
1158 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1160 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1162 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1163 canonicalized
= true;
1166 /* Limit recursion, see gimple_resimplify1. */
1167 static unsigned depth
;
1170 if (dump_file
&& (dump_flags
& TDF_FOLDING
))
1171 fprintf (dump_file
, "Aborting expression simplification due to "
1172 "deep recursion\n");
1177 gimple_match_op
res_op2 (*res_op
);
1178 if (gimple_simplify (&res_op2
, seq
, valueize
,
1179 res_op
->code
, res_op
->type
,
1180 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1189 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1192 return canonicalized
;
1195 /* Helper that matches and simplifies the toplevel result from
1196 a gimple_simplify run (where we don't want to build
1197 a stmt in case it's used in in-place folding). Replaces
1198 RES_OP with a simplified and/or canonicalized result and
1199 returns whether any change was made. */
1202 gimple_resimplify5 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1203 tree (*valueize
)(tree
))
1205 /* No constant folding is defined for five-operand functions. */
1207 /* Canonicalize operand order. */
1208 bool canonicalized
= false;
1209 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1211 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1213 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1214 canonicalized
= true;
1217 gimple_match_op
res_op2 (*res_op
);
1218 if (gimple_simplify (&res_op2
, seq
, valueize
,
1219 res_op
->code
, res_op
->type
,
1220 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1221 res_op
->ops
[3], res_op
->ops
[4]))
1227 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1230 return canonicalized
;
1233 /* Helper that matches and simplifies the toplevel result from
1234 a gimple_simplify run (where we don't want to build
1235 a stmt in case it's used in in-place folding). Replaces
1236 RES_OP with a simplified and/or canonicalized result and
1237 returns whether any change was made. */
1240 gimple_resimplify6 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1241 tree (*valueize
)(tree
))
1243 /* No constant folding is defined for six-operand functions. */
1245 /* Canonicalize operand order. */
1246 bool canonicalized
= false;
1247 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1249 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1251 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1252 canonicalized
= true;
1255 gimple_match_op
res_op2 (*res_op
);
1256 if (gimple_simplify (&res_op2
, seq
, valueize
,
1257 res_op
->code
, res_op
->type
,
1258 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1259 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5]))
1265 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1268 return canonicalized
;
1271 /* Helper that matches and simplifies the toplevel result from
1272 a gimple_simplify run (where we don't want to build
1273 a stmt in case it's used in in-place folding). Replaces
1274 RES_OP with a simplified and/or canonicalized result and
1275 returns whether any change was made. */
1278 gimple_resimplify7 (gimple_seq
*seq
, gimple_match_op
*res_op
,
1279 tree (*valueize
)(tree
))
1281 /* No constant folding is defined for seven-operand functions. */
1283 /* Canonicalize operand order. */
1284 bool canonicalized
= false;
1285 int argno
= first_commutative_argument (res_op
->code
, res_op
->type
);
1287 && tree_swap_operands_p (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]))
1289 std::swap (res_op
->ops
[argno
], res_op
->ops
[argno
+ 1]);
1290 canonicalized
= true;
1293 gimple_match_op
res_op2 (*res_op
);
1294 if (gimple_simplify (&res_op2
, seq
, valueize
,
1295 res_op
->code
, res_op
->type
,
1296 res_op
->ops
[0], res_op
->ops
[1], res_op
->ops
[2],
1297 res_op
->ops
[3], res_op
->ops
[4], res_op
->ops
[5],
1304 if (maybe_resimplify_conditional_op (seq
, res_op
, valueize
))
1307 return canonicalized
;
1310 /* Return a canonical form for CODE when operating on TYPE. The idea
1311 is to remove redundant ways of representing the same operation so
1312 that code_helpers can be hashed and compared for equality.
1314 The only current canonicalization is to replace built-in functions
1315 with internal functions, in cases where internal-fn.def defines
1316 such an internal function.
1318 Note that the new code_helper cannot necessarily be used in place of
1319 the original code_helper. For example, the new code_helper might be
1320 an internal function that the target does not support. */
1323 canonicalize_code (code_helper code
, tree type
)
1325 if (code
.is_fn_code ())
1326 return associated_internal_fn (combined_fn (code
), type
);
1330 /* Return true if CODE is a binary operation and if CODE is commutative when
1331 operating on type TYPE. */
1334 commutative_binary_op_p (code_helper code
, tree type
)
1336 if (code
.is_tree_code ())
1337 return commutative_tree_code (tree_code (code
));
1338 auto cfn
= combined_fn (code
);
1339 return commutative_binary_fn_p (associated_internal_fn (cfn
, type
));
1342 /* Return true if CODE represents a ternary operation and if the first two
1343 operands are commutative when CODE is operating on TYPE. */
1346 commutative_ternary_op_p (code_helper code
, tree type
)
1348 if (code
.is_tree_code ())
1349 return commutative_ternary_tree_code (tree_code (code
));
1350 auto cfn
= combined_fn (code
);
1351 return commutative_ternary_fn_p (associated_internal_fn (cfn
, type
));
1354 /* If CODE is commutative in two consecutive operands, return the
1355 index of the first, otherwise return -1. */
1358 first_commutative_argument (code_helper code
, tree type
)
1360 if (code
.is_tree_code ())
1362 auto tcode
= tree_code (code
);
1363 if (commutative_tree_code (tcode
)
1364 || commutative_ternary_tree_code (tcode
))
1368 auto cfn
= combined_fn (code
);
1369 return first_commutative_argument (associated_internal_fn (cfn
, type
));
1372 /* Return true if CODE is a binary operation that is associative when
1373 operating on type TYPE. */
1376 associative_binary_op_p (code_helper code
, tree type
)
1378 if (code
.is_tree_code ())
1379 return associative_tree_code (tree_code (code
));
1380 auto cfn
= combined_fn (code
);
1381 return associative_binary_fn_p (associated_internal_fn (cfn
, type
));
1384 /* Return true if the target directly supports operation CODE on type TYPE.
1385 QUERY_TYPE acts as for optab_for_tree_code. */
1388 directly_supported_p (code_helper code
, tree type
, optab_subtype query_type
)
1390 if (code
.is_tree_code ())
1392 direct_optab optab
= optab_for_tree_code (tree_code (code
), type
,
1394 return (optab
!= unknown_optab
1395 && optab_handler (optab
, TYPE_MODE (type
)) != CODE_FOR_nothing
);
1397 gcc_assert (query_type
== optab_default
1398 || (query_type
== optab_vector
&& VECTOR_TYPE_P (type
))
1399 || (query_type
== optab_scalar
&& !VECTOR_TYPE_P (type
)));
1400 internal_fn ifn
= associated_internal_fn (combined_fn (code
), type
);
1401 return (direct_internal_fn_p (ifn
)
1402 && direct_internal_fn_supported_p (ifn
, type
, OPTIMIZE_FOR_SPEED
));
1405 /* As above, overloading the function for conversion-type optabs. */
1407 directly_supported_p (code_helper code
, tree otype
, tree itype
,
1408 optab_subtype query_type
)
1410 if (code
.is_tree_code ())
1412 convert_optab optab
= optab_for_tree_code (tree_code (code
), itype
,
1414 return (optab
!= unknown_optab
1415 && convert_optab_handler (optab
, TYPE_MODE (otype
),
1416 TYPE_MODE (itype
)) != CODE_FOR_nothing
);
1418 gcc_assert (query_type
== optab_default
1419 || (query_type
== optab_vector
&& VECTOR_TYPE_P (itype
))
1420 || (query_type
== optab_scalar
&& !VECTOR_TYPE_P (itype
)));
1421 internal_fn ifn
= associated_internal_fn (combined_fn (code
), itype
);
1422 return (direct_internal_fn_p (ifn
)
1423 && direct_internal_fn_supported_p (ifn
, tree_pair (otype
, itype
),
1424 OPTIMIZE_FOR_SPEED
));
1428 /* A wrapper around the internal-fn.cc versions of get_conditional_internal_fn
1429 for a code_helper CODE operating on type TYPE. */
1432 get_conditional_internal_fn (code_helper code
, tree type
)
1434 if (code
.is_tree_code ())
1435 return get_conditional_internal_fn (tree_code (code
));
1436 auto cfn
= combined_fn (code
);
1437 return get_conditional_internal_fn (associated_internal_fn (cfn
, type
));