1 /* Preamble and helpers for the autogenerated generic-match.cc file.
2 Copyright (C) 2014-2024 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"
36 #include "case-cfn-macros.h"
40 #include "optabs-tree.h"
44 #include "langhooks.h"
45 #include "tree-pass.h"
49 /* Routine to determine if the types T1 and T2 are effectively
50 the same for GENERIC. If T1 or T2 is not a type, the test
51 applies to their TREE_TYPE. */
54 types_match (tree t1
, tree t2
)
61 return TYPE_MAIN_VARIANT (t1
) == TYPE_MAIN_VARIANT (t2
);
64 /* Routine to determine if the types T1, T2 and T3 are effectively
65 the same for GENERIC. If T1, T2 or T2 is not a type, the test
66 applies to their TREE_TYPE. */
69 types_match (tree t1
, tree t2
, tree t3
)
71 return types_match (t1
, t2
) && types_match (t2
, t3
);
74 /* Return if T has a single use. For GENERIC, we assume this is
78 single_use (tree t ATTRIBUTE_UNUSED
)
83 /* Return true if math operations should be canonicalized,
84 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
87 canonicalize_math_p ()
89 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_opt_math
) == 0;
92 /* Return true if math operations that are beneficial only after
93 vectorization should be canonicalized. */
96 canonicalize_math_after_vectorization_p ()
101 /* Return true if we can still perform transformations that may introduce
102 vector operations that are not supported by the target. Vector lowering
103 normally handles those, but after that pass, it becomes unsafe. */
106 optimize_vectors_before_lowering_p ()
108 return !cfun
|| (cfun
->curr_properties
& PROP_gimple_lvec
) == 0;
111 /* Return true if successive divisions can be optimized.
112 Defer to GIMPLE opts. */
115 optimize_successive_divisions_p (tree
, tree
)
120 /* Returns true if the expression T has no side effects
121 including not trapping. */
123 expr_no_side_effects_p (tree t
)
125 if (TREE_SIDE_EFFECTS (t
))
127 if (generic_expr_could_trap_p (t
))
132 /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
133 same type. The types can differ through nop conversions. */
136 bitwise_equal_p (tree expr1
, tree expr2
)
142 if (!tree_nop_conversion_p (TREE_TYPE (expr1
), TREE_TYPE (expr2
)))
144 if (TREE_CODE (expr1
) == INTEGER_CST
&& TREE_CODE (expr2
) == INTEGER_CST
)
145 return wi::to_wide (expr1
) == wi::to_wide (expr2
);
146 return operand_equal_p (expr1
, expr2
, 0);
149 /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
150 but not necessarily same type.
151 The types can differ through nop conversions. */
154 bitwise_inverted_equal_p (tree expr1
, tree expr2
, bool &wascmp
)
161 if (!tree_nop_conversion_p (TREE_TYPE (expr1
), TREE_TYPE (expr2
)))
163 tree cst1
= uniform_integer_cst_p (expr1
);
164 tree cst2
= uniform_integer_cst_p (expr2
);
166 return wi::to_wide (cst1
) == ~wi::to_wide (cst2
);
167 if (operand_equal_p (expr1
, expr2
, 0))
169 if (TREE_CODE (expr1
) == BIT_NOT_EXPR
170 && bitwise_equal_p (TREE_OPERAND (expr1
, 0), expr2
))
172 if (TREE_CODE (expr2
) == BIT_NOT_EXPR
173 && bitwise_equal_p (expr1
, TREE_OPERAND (expr2
, 0)))
176 /* `X ^ CST` and `X ^ ~CST` match for ~. */
177 if (TREE_CODE (expr1
) == BIT_XOR_EXPR
&& TREE_CODE (expr2
) == BIT_XOR_EXPR
178 && bitwise_equal_p (TREE_OPERAND (expr1
, 0), TREE_OPERAND (expr2
, 0)))
180 tree cst1
= uniform_integer_cst_p (TREE_OPERAND (expr1
, 1));
181 tree cst2
= uniform_integer_cst_p (TREE_OPERAND (expr2
, 1));
182 if (cst1
&& cst2
&& wi::to_wide (cst1
) == ~wi::to_wide (cst2
))
185 if (COMPARISON_CLASS_P (expr1
)
186 && COMPARISON_CLASS_P (expr2
))
188 tree op10
= TREE_OPERAND (expr1
, 0);
189 tree op20
= TREE_OPERAND (expr2
, 0);
191 if (!operand_equal_p (op10
, op20
))
193 tree op11
= TREE_OPERAND (expr1
, 1);
194 tree op21
= TREE_OPERAND (expr2
, 1);
195 if (!operand_equal_p (op11
, op21
))
197 if (invert_tree_comparison (TREE_CODE (expr1
),
199 == TREE_CODE (expr2
))