[strub] improve handling of indirected volatile parms [PR112938]
[official-gcc.git] / gcc / gimple-match-head.cc
blob5f8a1a1ad8e3ebc30ff06b91c69fe5c2e92a68c6
1 /* Preamble and helpers for the autogenerated gimple-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
9 version.
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.
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/>. */
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 "gimple-iterator.h"
35 #include "gimple-fold.h"
36 #include "calls.h"
37 #include "tree-dfa.h"
38 #include "builtins.h"
39 #include "gimple-match.h"
40 #include "tree-pass.h"
41 #include "internal-fn.h"
42 #include "case-cfn-macros.h"
43 #include "gimplify.h"
44 #include "optabs-tree.h"
45 #include "tree-eh.h"
46 #include "dbgcnt.h"
47 #include "tm.h"
48 #include "gimple-range.h"
49 #include "langhooks.h"
50 #include "attribs.h"
51 #include "asan.h"
53 tree do_valueize (tree, tree (*)(tree), bool &);
54 tree do_valueize (tree (*)(tree), tree);
56 /* Helper for the autogenerated code, get at the definition of NAME when
57 VALUEIZE allows that. */
59 inline gimple *
60 get_def (tree (*valueize)(tree), tree name)
62 if (valueize && ! valueize (name))
63 return NULL;
64 return SSA_NAME_DEF_STMT (name);
67 /* Routine to determine if the types T1 and T2 are effectively
68 the same for GIMPLE. If T1 or T2 is not a type, the test
69 applies to their TREE_TYPE. */
71 static inline bool
72 types_match (tree t1, tree t2)
74 if (!TYPE_P (t1))
75 t1 = TREE_TYPE (t1);
76 if (!TYPE_P (t2))
77 t2 = TREE_TYPE (t2);
79 return types_compatible_p (t1, t2);
82 /* Return if T has a single use. For GIMPLE, we also allow any
83 non-SSA_NAME (ie constants) and zero uses to cope with uses
84 that aren't linked up yet. */
86 static bool
87 single_use (const_tree) ATTRIBUTE_PURE;
89 static bool
90 single_use (const_tree t)
92 if (TREE_CODE (t) != SSA_NAME)
93 return true;
95 /* Inline return has_zero_uses (t) || has_single_use (t); */
96 const ssa_use_operand_t *const head = &(SSA_NAME_IMM_USE_NODE (t));
97 const ssa_use_operand_t *ptr;
98 bool single = false;
100 for (ptr = head->next; ptr != head; ptr = ptr->next)
101 if (USE_STMT(ptr) && !is_gimple_debug (USE_STMT (ptr)))
103 if (single)
104 return false;
105 single = true;
107 return true;
110 /* Return true if math operations should be canonicalized,
111 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */
113 static inline bool
114 canonicalize_math_p ()
116 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0;
119 /* Return true if math operations that are beneficial only after
120 vectorization should be canonicalized. */
122 static inline bool
123 canonicalize_math_after_vectorization_p ()
125 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0;
128 /* Return true if we can still perform transformations that may introduce
129 vector operations that are not supported by the target. Vector lowering
130 normally handles those, but after that pass, it becomes unsafe. */
132 static inline bool
133 optimize_vectors_before_lowering_p ()
135 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) == 0;
138 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x).
139 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0
140 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...>
141 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1)
142 will likely be exact, while exp (log (arg0) * arg1) might be not.
143 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */
145 static bool
146 optimize_pow_to_exp (tree arg0, tree arg1)
148 gcc_assert (TREE_CODE (arg0) == REAL_CST);
149 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0))))
150 return true;
152 if (TREE_CODE (arg1) != SSA_NAME)
153 return true;
155 gimple *def = SSA_NAME_DEF_STMT (arg1);
156 gphi *phi = dyn_cast <gphi *> (def);
157 tree cst1 = NULL_TREE;
158 enum tree_code code = ERROR_MARK;
159 if (!phi)
161 if (!is_gimple_assign (def))
162 return true;
163 code = gimple_assign_rhs_code (def);
164 switch (code)
166 case PLUS_EXPR:
167 case MINUS_EXPR:
168 break;
169 default:
170 return true;
172 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME
173 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST)
174 return true;
176 cst1 = gimple_assign_rhs2 (def);
178 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def)));
179 if (!phi)
180 return true;
183 tree cst2 = NULL_TREE;
184 int n = gimple_phi_num_args (phi);
185 for (int i = 0; i < n; i++)
187 tree arg = PHI_ARG_DEF (phi, i);
188 if (TREE_CODE (arg) != REAL_CST)
189 continue;
190 else if (cst2 == NULL_TREE)
191 cst2 = arg;
192 else if (!operand_equal_p (cst2, arg, 0))
193 return true;
196 if (cst1 && cst2)
197 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1);
198 if (cst2
199 && TREE_CODE (cst2) == REAL_CST
200 && real_isinteger (TREE_REAL_CST_PTR (cst2),
201 TYPE_MODE (TREE_TYPE (cst2))))
202 return false;
203 return true;
206 /* Return true if a division INNER_DIV / DIVISOR where INNER_DIV
207 is another division can be optimized. Don't optimize if INNER_DIV
208 is used in a TRUNC_MOD_EXPR with DIVISOR as second operand. */
210 static bool
211 optimize_successive_divisions_p (tree divisor, tree inner_div)
213 if (!gimple_in_ssa_p (cfun))
214 return false;
216 imm_use_iterator imm_iter;
217 use_operand_p use_p;
218 FOR_EACH_IMM_USE_FAST (use_p, imm_iter, inner_div)
220 gimple *use_stmt = USE_STMT (use_p);
221 if (!is_gimple_assign (use_stmt)
222 || gimple_assign_rhs_code (use_stmt) != TRUNC_MOD_EXPR
223 || !operand_equal_p (gimple_assign_rhs2 (use_stmt), divisor, 0))
224 continue;
225 return false;
227 return true;
230 /* Return true if EXPR1 and EXPR2 have the same value, but not necessarily
231 same type. The types can differ through nop conversions. */
232 #define bitwise_equal_p(expr1, expr2) \
233 gimple_bitwise_equal_p (expr1, expr2, valueize)
235 bool gimple_nop_convert (tree, tree *, tree (*) (tree));
237 /* Helper function for bitwise_equal_p macro. */
239 static inline bool
240 gimple_bitwise_equal_p (tree expr1, tree expr2, tree (*valueize) (tree))
242 if (expr1 == expr2)
243 return true;
244 if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
245 return false;
246 if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
247 return wi::to_wide (expr1) == wi::to_wide (expr2);
248 if (operand_equal_p (expr1, expr2, 0))
249 return true;
250 tree expr3, expr4;
251 if (!gimple_nop_convert (expr1, &expr3, valueize))
252 expr3 = expr1;
253 if (!gimple_nop_convert (expr2, &expr4, valueize))
254 expr4 = expr2;
255 if (expr1 != expr3)
257 if (operand_equal_p (expr3, expr2, 0))
258 return true;
259 if (expr2 != expr4 && operand_equal_p (expr3, expr4, 0))
260 return true;
262 if (expr2 != expr4 && operand_equal_p (expr1, expr4, 0))
263 return true;
264 return false;
267 /* Return true if EXPR1 and EXPR2 have the bitwise opposite value,
268 but not necessarily same type.
269 The types can differ through nop conversions. */
270 #define bitwise_inverted_equal_p(expr1, expr2, wascmp) \
271 gimple_bitwise_inverted_equal_p (expr1, expr2, wascmp, valueize)
274 bool gimple_bit_not_with_nop (tree, tree *, tree (*) (tree));
275 bool gimple_maybe_cmp (tree, tree *, tree (*) (tree));
277 /* Helper function for bitwise_inverted_equal_p macro. */
279 static inline bool
280 gimple_bitwise_inverted_equal_p (tree expr1, tree expr2, bool &wascmp, tree (*valueize) (tree))
282 wascmp = false;
283 if (expr1 == expr2)
284 return false;
285 if (!tree_nop_conversion_p (TREE_TYPE (expr1), TREE_TYPE (expr2)))
286 return false;
287 if (TREE_CODE (expr1) == INTEGER_CST && TREE_CODE (expr2) == INTEGER_CST)
288 return wi::to_wide (expr1) == ~wi::to_wide (expr2);
289 if (operand_equal_p (expr1, expr2, 0))
290 return false;
292 tree other;
293 /* Try if EXPR1 was defined as ~EXPR2. */
294 if (gimple_bit_not_with_nop (expr1, &other, valueize))
296 if (operand_equal_p (other, expr2, 0))
297 return true;
298 tree expr4;
299 if (gimple_nop_convert (expr2, &expr4, valueize)
300 && operand_equal_p (other, expr4, 0))
301 return true;
303 /* Try if EXPR2 was defined as ~EXPR1. */
304 if (gimple_bit_not_with_nop (expr2, &other, valueize))
306 if (operand_equal_p (other, expr1, 0))
307 return true;
308 tree expr3;
309 if (gimple_nop_convert (expr1, &expr3, valueize)
310 && operand_equal_p (other, expr3, 0))
311 return true;
314 /* If neither are defined by BIT_NOT, try to see if
315 both are defined by comparisons and see if they are
316 complementary (inversion) of each other. */
317 tree newexpr1, newexpr2;
318 if (!gimple_maybe_cmp (expr1, &newexpr1, valueize))
319 return false;
320 if (!gimple_maybe_cmp (expr2, &newexpr2, valueize))
321 return false;
323 gimple *d1 = get_def (valueize, newexpr1);
324 gassign *a1 = dyn_cast <gassign *> (d1);
325 gimple *d2 = get_def (valueize, newexpr2);
326 gassign *a2 = dyn_cast <gassign *> (d2);
327 tree op10 = do_valueize (valueize, gimple_assign_rhs1 (a1));
328 tree op20 = do_valueize (valueize, gimple_assign_rhs1 (a2));
329 if (!operand_equal_p (op10, op20))
330 return false;
331 tree op11 = do_valueize (valueize, gimple_assign_rhs2 (a1));
332 tree op21 = do_valueize (valueize, gimple_assign_rhs2 (a2));
333 if (!operand_equal_p (op11, op21))
334 return false;
335 wascmp = true;
336 tree_code ac1 = gimple_assign_rhs_code (a1);
337 tree_code ac2 = gimple_assign_rhs_code (a2);
338 /* Match `^` against `==` but this should only
339 happen when the type is a 1bit precision integer. */
340 if (ac1 == BIT_XOR_EXPR)
342 tree type = TREE_TYPE (newexpr1);
343 gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1);
344 return ac2 == EQ_EXPR;
346 if (ac2 == BIT_XOR_EXPR)
348 tree type = TREE_TYPE (newexpr1);
349 gcc_assert (INTEGRAL_TYPE_P (type) && TYPE_PRECISION (type) == 1);
350 return ac1 == EQ_EXPR;
352 if (invert_tree_comparison (ac1, HONOR_NANS (op10)) == ac2)
353 return true;
354 return false;