Branch data Line data Source code
1 : : /* Preamble and helpers for the autogenerated generic-match.cc file.
2 : : Copyright (C) 2014-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 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
9 : : version.
10 : :
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
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 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "backend.h"
24 : : #include "target.h"
25 : : #include "rtl.h"
26 : : #include "tree.h"
27 : : #include "gimple.h"
28 : : #include "ssa.h"
29 : : #include "cgraph.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 "tree-dfa.h"
35 : : #include "builtins.h"
36 : : #include "case-cfn-macros.h"
37 : : #include "gimplify.h"
38 : : #include "memmodel.h"
39 : : #include "optabs.h"
40 : : #include "optabs-tree.h"
41 : : #include "dbgcnt.h"
42 : : #include "tm.h"
43 : : #include "tree-eh.h"
44 : : #include "langhooks.h"
45 : : #include "tree-pass.h"
46 : : #include "attribs.h"
47 : : #include "asan.h"
48 : : #include "gimple-iterator.h"
49 : : #include "gimple-fold.h"
50 : :
51 : : /* Routine to determine if the types T1 and T2 are effectively
52 : : the same for GENERIC. If T1 or T2 is not a type, the test
53 : : applies to their TREE_TYPE. */
54 : :
55 : : static inline bool
56 : 70800408 : types_match (tree t1, tree t2)
57 : : {
58 : 70800408 : if (!TYPE_P (t1))
59 : 6243693 : t1 = TREE_TYPE (t1);
60 : 70800408 : if (!TYPE_P (t2))
61 : 5865222 : t2 = TREE_TYPE (t2);
62 : :
63 : 70800408 : return TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2);
64 : : }
65 : :
66 : : /* Routine to determine if the types T1, T2 and T3 are effectively
67 : : the same for GENERIC. If T1, T2 or T2 is not a type, the test
68 : : applies to their TREE_TYPE. */
69 : :
70 : : static inline bool
71 : 0 : types_match (tree t1, tree t2, tree t3)
72 : : {
73 : 0 : return types_match (t1, t2) && types_match (t2, t3);
74 : : }
75 : :
76 : : /* Return if T has a single use. For GENERIC, we assume this is
77 : : always true. */
78 : :
79 : : static inline bool
80 : : single_use (tree t ATTRIBUTE_UNUSED)
81 : : {
82 : : return true;
83 : : }
84 : :
85 : : /* Return true if math operations should be canonicalized,
86 : : e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
87 : :
88 : : static inline bool
89 : 1651 : canonicalize_math_p ()
90 : : {
91 : 1651 : return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
92 : : }
93 : :
94 : : /* Return true if math operations that are beneficial only after
95 : : vectorization should be canonicalized. */
96 : :
97 : : static inline bool
98 : : canonicalize_math_after_vectorization_p ()
99 : : {
100 : : return false;
101 : : }
102 : :
103 : : /* Return true if we can still perform transformations that may introduce
104 : : vector operations that are not supported by the target. Vector lowering
105 : : normally handles those, but after that pass, it becomes unsafe. */
106 : :
107 : : static inline bool
108 : 2470 : optimize_vectors_before_lowering_p ()
109 : : {
110 : 2470 : return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
111 : : }
112 : :
113 : : /* Return true if successive divisions can be optimized.
114 : : Defer to GIMPLE opts. */
115 : :
116 : : static inline bool
117 : : optimize_successive_divisions_p (tree, tree)
118 : : {
119 : : return false;
120 : : }
121 : :
122 : : /* Returns true if the expression T has no side effects
123 : : including not trapping. */
124 : : static inline bool
125 : 16 : expr_no_side_effects_p (tree t)
126 : : {
127 : 16 : if (TREE_SIDE_EFFECTS (t))
128 : : return false;
129 : 16 : if (generic_expr_could_trap_p (t))
130 : : return false;
131 : : return true;
132 : : }
133 : :
134 : : /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
135 : : same type. The types can differ through nop conversions. */
136 : :
137 : : static inline bool
138 : 508542 : bitwise_equal_p (tree expr1, tree expr2)
139 : : {
140 : 508542 : STRIP_NOPS (expr1);
141 : 508542 : STRIP_NOPS (expr2);
142 : 508542 : if (expr1 == expr2)
143 : : return true;
144 : 477424 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
145 : : return false;
146 : 244579 : if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
147 : 0 : return wi::to_wide (expr1) == wi::to_wide (expr2);
148 : 244579 : return operand_equal_p (expr1, expr2, 0);
149 : : }
150 : :
151 : : /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
152 : : but not necessarily same type.
153 : : The types can differ through nop conversions. */
154 : :
155 : : static inline bool
156 : 47991598 : bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp)
157 : : {
158 : 47991598 : STRIP_NOPS (expr1);
159 : 47991598 : STRIP_NOPS (expr2);
160 : 47991598 : wascmp = false;
161 : 47991598 : if (expr1 == expr2)
162 : : return false;
163 : 47991171 : if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
164 : : return false;
165 : 47991171 : tree cst1 = uniform_integer_cst_p (expr1);
166 : 47991171 : tree cst2 = uniform_integer_cst_p (expr2);
167 : 47991171 : if (cst1 && cst2)
168 : 98830 : return wi::to_wide (cst1) == ~wi::to_wide (cst2);
169 : 47892341 : if (operand_equal_p (expr1, expr2, 0))
170 : : return false;
171 : 47892170 : if (TREE_CODE (expr1) == BIT_NOT_EXPR
172 : 47892170 : && bitwise_equal_p (TREE_OPERAND (expr1, 0), expr2))
173 : : return true;
174 : 47892078 : if (TREE_CODE (expr2) == BIT_NOT_EXPR
175 : 47892078 : && bitwise_equal_p (expr1, TREE_OPERAND (expr2, 0)))
176 : : return true;
177 : :
178 : : /* `X ^ CST` and `X ^ ~CST` match for ~. */
179 : 33763 : if (TREE_CODE (expr1) == BIT_XOR_EXPR && TREE_CODE (expr2) == BIT_XOR_EXPR
180 : 47892526 : && bitwise_equal_p (TREE_OPERAND (expr1, 0), TREE_OPERAND (expr2, 0)))
181 : : {
182 : 9 : tree cst1 = uniform_integer_cst_p (TREE_OPERAND (expr1, 1));
183 : 9 : tree cst2 = uniform_integer_cst_p (TREE_OPERAND (expr2, 1));
184 : 16 : if (cst1 && cst2 && wi::to_wide (cst1) == ~wi::to_wide (cst2))
185 : : return true;
186 : : }
187 : 47891658 : if (COMPARISON_CLASS_P (expr1)
188 : 350087 : && COMPARISON_CLASS_P (expr2))
189 : : {
190 : 83037 : tree op10 = TREE_OPERAND (expr1, 0);
191 : 83037 : tree op20 = TREE_OPERAND (expr2, 0);
192 : 83037 : wascmp = true;
193 : 83037 : if (!operand_equal_p (op10, op20))
194 : : return false;
195 : 3368 : tree op11 = TREE_OPERAND (expr1, 1);
196 : 3368 : tree op21 = TREE_OPERAND (expr2, 1);
197 : 3368 : if (!operand_equal_p (op11, op21))
198 : : return false;
199 : 1152 : if (invert_tree_comparison (TREE_CODE (expr1),
200 : 1152 : HONOR_NANS (op10))
201 : 1152 : == TREE_CODE (expr2))
202 : : return true;
203 : : }
204 : : return false;
205 : : }
|