annotate gcc/vr-values.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1 /* Support routines for Value Range Propagation (VRP).
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4 This file is part of GCC.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
5
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
8 the Free Software Foundation; either version 3, or (at your option)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
9 any later version.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
10
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
14 GNU General Public License for more details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
15
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
19
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
20 #include "config.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
21 #include "system.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
22 #include "coretypes.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
23 #include "backend.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
24 #include "insn-codes.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
25 #include "tree.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
26 #include "gimple.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
27 #include "ssa.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
28 #include "optabs-tree.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
29 #include "gimple-pretty-print.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
30 #include "diagnostic-core.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
31 #include "flags.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
32 #include "fold-const.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
33 #include "calls.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
34 #include "cfganal.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
35 #include "gimple-fold.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
36 #include "gimple-iterator.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
37 #include "tree-cfg.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
38 #include "tree-ssa-loop-niter.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
39 #include "tree-ssa-loop.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
40 #include "intl.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
41 #include "cfgloop.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
42 #include "tree-scalar-evolution.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
43 #include "tree-ssa-propagate.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
44 #include "tree-chrec.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
45 #include "omp-general.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
46 #include "case-cfn-macros.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
47 #include "alloc-pool.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
48 #include "attribs.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
49 #include "range.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
50 #include "vr-values.h"
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
51 #include "cfghooks.h"
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
52 #include "range-op.h"
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
53
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
54 /* Set value range VR to a non-negative range of type TYPE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
55
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
56 static inline void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
57 set_value_range_to_nonnegative (value_range_equiv *vr, tree type)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
58 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
59 tree zero = build_int_cst (type, 0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
60 vr->update (zero, vrp_val_max (type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
61 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
62
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
63 /* Set value range VR to a range of a truthvalue of type TYPE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
64
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
65 static inline void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
66 set_value_range_to_truthvalue (value_range_equiv *vr, tree type)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
67 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
68 if (TYPE_PRECISION (type) == 1)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
69 vr->set_varying (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
70 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
71 vr->update (build_int_cst (type, 0), build_int_cst (type, 1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
72 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
73
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
74 /* Return the lattice entry for VAR or NULL if it doesn't exist or cannot
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
75 be initialized. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
76
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
77 value_range_equiv *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
78 vr_values::get_lattice_entry (const_tree var)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
79 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
80 value_range_equiv *vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
81 tree sym;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
82 unsigned ver = SSA_NAME_VERSION (var);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
83
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
84 /* If we query the entry for a new SSA name avoid reallocating the lattice
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
85 since we should get here at most from the substitute-and-fold stage which
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
86 will never try to change values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
87 if (ver >= num_vr_values)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
88 return NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
89
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
90 vr = vr_value[ver];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
91 if (vr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
92 return vr;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
93
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
94 /* Create a default value range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
95 vr_value[ver] = vr = vrp_value_range_pool.allocate ();
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
96
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
97 /* After propagation finished return varying. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
98 if (values_propagated)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
99 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
100 vr->set_varying (TREE_TYPE (var));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
101 return vr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
102 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
103
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
104 vr->set_undefined ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
105
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
106 /* If VAR is a default definition of a parameter, the variable can
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
107 take any value in VAR's type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
108 if (SSA_NAME_IS_DEFAULT_DEF (var))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
109 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
110 sym = SSA_NAME_VAR (var);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
111 if (TREE_CODE (sym) == PARM_DECL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
112 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
113 /* Try to use the "nonnull" attribute to create ~[0, 0]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
114 anti-ranges for pointers. Note that this is only valid with
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
115 default definitions of PARM_DECLs. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
116 if (POINTER_TYPE_P (TREE_TYPE (sym))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
117 && (nonnull_arg_p (sym)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
118 || get_ptr_nonnull (var)))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
119 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
120 vr->set_nonzero (TREE_TYPE (sym));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
121 vr->equiv_clear ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
122 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
123 else if (INTEGRAL_TYPE_P (TREE_TYPE (sym)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
124 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
125 get_range_info (var, *vr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
126 if (vr->undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
127 vr->set_varying (TREE_TYPE (sym));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
128 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
129 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
130 vr->set_varying (TREE_TYPE (sym));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
131 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
132 else if (TREE_CODE (sym) == RESULT_DECL
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
133 && DECL_BY_REFERENCE (sym))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
134 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
135 vr->set_nonzero (TREE_TYPE (sym));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
136 vr->equiv_clear ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
137 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
138 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
139
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
140 return vr;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
141 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
142
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
143 /* Return value range information for VAR.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
144
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
145 If we have no values ranges recorded (ie, VRP is not running), then
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
146 return NULL. Otherwise create an empty range if none existed for VAR. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
147
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
148 const value_range_equiv *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
149 vr_values::get_value_range (const_tree var)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
150 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
151 /* If we have no recorded ranges, then return NULL. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
152 if (!vr_value)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
153 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
154
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
155 value_range_equiv *vr = get_lattice_entry (var);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
156
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
157 /* Reallocate the lattice if needed. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
158 if (!vr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
159 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
160 unsigned int old_sz = num_vr_values;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
161 num_vr_values = num_ssa_names + num_ssa_names / 10;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
162 vr_value = XRESIZEVEC (value_range_equiv *, vr_value, num_vr_values);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
163 for ( ; old_sz < num_vr_values; old_sz++)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
164 vr_value [old_sz] = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
165
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
166 /* Now that the lattice has been resized, we should never fail. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
167 vr = get_lattice_entry (var);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
168 gcc_assert (vr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
169 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
170
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
171 return vr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
172 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
173
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
174 /* Set the lattice entry for DEF to VARYING. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
175
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
176 void
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
177 vr_values::set_def_to_varying (const_tree def)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
178 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
179 value_range_equiv *vr = get_lattice_entry (def);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
180 if (vr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
181 vr->set_varying (TREE_TYPE (def));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
182 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
183
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
184 /* Set value-ranges of all SSA names defined by STMT to varying. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
185
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
186 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
187 vr_values::set_defs_to_varying (gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
188 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
189 ssa_op_iter i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
190 tree def;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
191 FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
192 set_def_to_varying (def);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
193 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
194
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
195 /* Update the value range and equivalence set for variable VAR to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
196 NEW_VR. Return true if NEW_VR is different from VAR's previous
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
197 value.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
198
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
199 NOTE: This function assumes that NEW_VR is a temporary value range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
200 object created for the sole purpose of updating VAR's range. The
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
201 storage used by the equivalence set from NEW_VR will be freed by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
202 this function. Do not call update_value_range when NEW_VR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
203 is the range object associated with another SSA name. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
204
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
205 bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
206 vr_values::update_value_range (const_tree var, value_range_equiv *new_vr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
207 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
208 value_range_equiv *old_vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
209 bool is_new;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
210
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
211 /* If there is a value-range on the SSA name from earlier analysis
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
212 factor that in. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
213 if (INTEGRAL_TYPE_P (TREE_TYPE (var)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
214 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
215 value_range_equiv nr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
216 get_range_info (var, nr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
217 if (!nr.undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
218 new_vr->intersect (&nr);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
219 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
220
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
221 /* Update the value range, if necessary. If we cannot allocate a lattice
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
222 entry for VAR keep it at VARYING. This happens when DOM feeds us stmts
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
223 with SSA names allocated after setting up the lattice. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
224 old_vr = get_lattice_entry (var);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
225 if (!old_vr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
226 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
227 is_new = !old_vr->equal_p (*new_vr, /*ignore_equivs=*/false);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
228
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
229 if (is_new)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
230 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
231 /* Do not allow transitions up the lattice. The following
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
232 is slightly more awkward than just new_vr->type < old_vr->type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
233 because VR_RANGE and VR_ANTI_RANGE need to be considered
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
234 the same. We may not have is_new when transitioning to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
235 UNDEFINED. If old_vr->type is VARYING, we shouldn't be
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
236 called, if we are anyway, keep it VARYING. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
237 if (old_vr->varying_p ())
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
238 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
239 new_vr->set_varying (TREE_TYPE (var));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
240 is_new = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
241 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
242 else if (new_vr->undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
243 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
244 old_vr->set_varying (TREE_TYPE (var));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
245 new_vr->set_varying (TREE_TYPE (var));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
246 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
247 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
248 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
249 old_vr->set (new_vr->min (), new_vr->max (), new_vr->equiv (),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
250 new_vr->kind ());
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
251 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
252
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
253 new_vr->equiv_clear ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
254
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
255 return is_new;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
256 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
257
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
258 /* Return true if value range VR involves exactly one symbol SYM. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
259
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
260 static bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
261 symbolic_range_based_on_p (value_range *vr, const_tree sym)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
262 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
263 bool neg, min_has_symbol, max_has_symbol;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
264 tree inv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
265
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
266 if (is_gimple_min_invariant (vr->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
267 min_has_symbol = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
268 else if (get_single_symbol (vr->min (), &neg, &inv) == sym)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
269 min_has_symbol = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
270 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
271 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
272
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
273 if (is_gimple_min_invariant (vr->max ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
274 max_has_symbol = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
275 else if (get_single_symbol (vr->max (), &neg, &inv) == sym)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
276 max_has_symbol = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
277 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
278 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
279
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
280 return (min_has_symbol || max_has_symbol);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
281 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
282
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
283 /* Return true if the result of assignment STMT is know to be non-zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
284
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
285 static bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
286 gimple_assign_nonzero_p (gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
287 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
288 enum tree_code code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
289 bool strict_overflow_p;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
290 switch (get_gimple_rhs_class (code))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
291 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
292 case GIMPLE_UNARY_RHS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
293 return tree_unary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
294 gimple_expr_type (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
295 gimple_assign_rhs1 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
296 &strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
297 case GIMPLE_BINARY_RHS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
298 return tree_binary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
299 gimple_expr_type (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
300 gimple_assign_rhs1 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
301 gimple_assign_rhs2 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
302 &strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
303 case GIMPLE_TERNARY_RHS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
304 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
305 case GIMPLE_SINGLE_RHS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
306 return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
307 &strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
308 case GIMPLE_INVALID_RHS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
309 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
310 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
311 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
312 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
313 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
314
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
315 /* Return true if STMT is known to compute a non-zero value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
316
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
317 static bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
318 gimple_stmt_nonzero_p (gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
319 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
320 switch (gimple_code (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
321 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
322 case GIMPLE_ASSIGN:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
323 return gimple_assign_nonzero_p (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
324 case GIMPLE_CALL:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
325 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
326 gcall *call_stmt = as_a<gcall *> (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
327 return (gimple_call_nonnull_result_p (call_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
328 || gimple_call_nonnull_arg (call_stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
329 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
330 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
331 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
332 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
333 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
334 /* Like tree_expr_nonzero_p, but this function uses value ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
335 obtained so far. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
336
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
337 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
338 vr_values::vrp_stmt_computes_nonzero (gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
339 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
340 if (gimple_stmt_nonzero_p (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
341 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
342
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
343 /* If we have an expression of the form &X->a, then the expression
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
344 is nonnull if X is nonnull. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
345 if (is_gimple_assign (stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
346 && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
347 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
348 tree expr = gimple_assign_rhs1 (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
349 poly_int64 bitsize, bitpos;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
350 tree offset;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
351 machine_mode mode;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
352 int unsignedp, reversep, volatilep;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
353 tree base = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
354 &bitpos, &offset, &mode, &unsignedp,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
355 &reversep, &volatilep);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
356
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
357 if (base != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
358 && TREE_CODE (base) == MEM_REF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
359 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
360 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
361 poly_offset_int off = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
362 bool off_cst = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
363 if (offset == NULL_TREE || TREE_CODE (offset) == INTEGER_CST)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
364 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
365 off = mem_ref_offset (base);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
366 if (offset)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
367 off += poly_offset_int::from (wi::to_poly_wide (offset),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
368 SIGNED);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
369 off <<= LOG2_BITS_PER_UNIT;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
370 off += bitpos;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
371 off_cst = true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
372 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
373 /* If &X->a is equal to X and X is ~[0, 0], the result is too.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
374 For -fdelete-null-pointer-checks -fno-wrapv-pointer we don't
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
375 allow going from non-NULL pointer to NULL. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
376 if ((off_cst && known_eq (off, 0))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
377 || (flag_delete_null_pointer_checks
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
378 && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
379 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
380 const value_range_equiv *vr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
381 = get_value_range (TREE_OPERAND (base, 0));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
382 if (!range_includes_zero_p (vr))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
383 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
384 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
385 /* If MEM_REF has a "positive" offset, consider it non-NULL
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
386 always, for -fdelete-null-pointer-checks also "negative"
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
387 ones. Punt for unknown offsets (e.g. variable ones). */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
388 if (!TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
389 && off_cst
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
390 && known_ne (off, 0)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
391 && (flag_delete_null_pointer_checks || known_gt (off, 0)))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
392 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
393 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
394 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
395
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
396 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
397 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
398
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
399 /* Returns true if EXPR is a valid value (as expected by compare_values) --
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
400 a gimple invariant, or SSA_NAME +- CST. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
401
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
402 static bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
403 valid_value_p (tree expr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
404 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
405 if (TREE_CODE (expr) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
406 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
407
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
408 if (TREE_CODE (expr) == PLUS_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
409 || TREE_CODE (expr) == MINUS_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
410 return (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
411 && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
412
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
413 return is_gimple_min_invariant (expr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
414 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
415
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
416 /* If OP has a value range with a single constant value return that,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
417 otherwise return NULL_TREE. This returns OP itself if OP is a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
418 constant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
419
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
420 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
421 vr_values::op_with_constant_singleton_value_range (tree op)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
422 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
423 if (is_gimple_min_invariant (op))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
424 return op;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
425
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
426 if (TREE_CODE (op) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
427 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
428
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
429 tree t;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
430 if (get_value_range (op)->singleton_p (&t))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
431 return t;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
432 return NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
433 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
434
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
435 /* Return true if op is in a boolean [0, 1] value-range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
436
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
437 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
438 vr_values::op_with_boolean_value_range_p (tree op)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
439 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
440 const value_range_equiv *vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
441
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
442 if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
443 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
444
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
445 if (integer_zerop (op)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
446 || integer_onep (op))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
447 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
448
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
449 if (TREE_CODE (op) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
450 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
451
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
452 vr = get_value_range (op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
453 return (vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
454 && integer_zerop (vr->min ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
455 && integer_onep (vr->max ()));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
456 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
457
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
458 /* Extract value range information for VAR when (OP COND_CODE LIMIT) is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
459 true and store it in *VR_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
460
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
461 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
462 vr_values::extract_range_for_var_from_comparison_expr (tree var,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
463 enum tree_code cond_code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
464 tree op, tree limit,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
465 value_range_equiv *vr_p)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
466 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
467 tree min, max, type;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
468 const value_range_equiv *limit_vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
469 type = TREE_TYPE (var);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
470
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
471 /* For pointer arithmetic, we only keep track of pointer equality
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
472 and inequality. If we arrive here with unfolded conditions like
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
473 _1 > _1 do not derive anything. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
474 if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
475 || limit == var)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
476 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
477 vr_p->set_varying (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
478 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
479 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
480
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
481 /* If LIMIT is another SSA name and LIMIT has a range of its own,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
482 try to use LIMIT's range to avoid creating symbolic ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
483 unnecessarily. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
484 limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
485
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
486 /* LIMIT's range is only interesting if it has any useful information. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
487 if (! limit_vr
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
488 || limit_vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
489 || limit_vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
490 || (limit_vr->symbolic_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
491 && ! (limit_vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
492 && (limit_vr->min () == limit_vr->max ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
493 || operand_equal_p (limit_vr->min (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
494 limit_vr->max (), 0)))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
495 limit_vr = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
496
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
497 /* Initially, the new range has the same set of equivalences of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
498 VAR's range. This will be revised before returning the final
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
499 value. Since assertions may be chained via mutually exclusive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
500 predicates, we will need to trim the set of equivalences before
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
501 we are done. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
502 gcc_assert (vr_p->equiv () == NULL);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
503 vr_p->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
504
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
505 /* Extract a new range based on the asserted comparison for VAR and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
506 LIMIT's value range. Notice that if LIMIT has an anti-range, we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
507 will only use it for equality comparisons (EQ_EXPR). For any
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
508 other kind of assertion, we cannot derive a range from LIMIT's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
509 anti-range that can be used to describe the new range. For
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
510 instance, ASSERT_EXPR <x_2, x_2 <= b_4>. If b_4 is ~[2, 10],
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
511 then b_4 takes on the ranges [-INF, 1] and [11, +INF]. There is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
512 no single range for x_2 that could describe LE_EXPR, so we might
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
513 as well build the range [b_4, +INF] for it.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
514 One special case we handle is extracting a range from a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
515 range test encoded as (unsigned)var + CST <= limit. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
516 if (TREE_CODE (op) == NOP_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
517 || TREE_CODE (op) == PLUS_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
518 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
519 if (TREE_CODE (op) == PLUS_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
520 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
521 min = fold_build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (op, 1)),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
522 TREE_OPERAND (op, 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
523 max = int_const_binop (PLUS_EXPR, limit, min);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
524 op = TREE_OPERAND (op, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
525 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
526 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
527 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
528 min = build_int_cst (TREE_TYPE (var), 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
529 max = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
530 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
531
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
532 /* Make sure to not set TREE_OVERFLOW on the final type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
533 conversion. We are willingly interpreting large positive
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
534 unsigned values as negative signed values here. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
535 min = force_fit_type (TREE_TYPE (var), wi::to_widest (min), 0, false);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
536 max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
537
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
538 /* We can transform a max, min range to an anti-range or
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
539 vice-versa. Use set_and_canonicalize which does this for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
540 us. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
541 if (cond_code == LE_EXPR)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
542 vr_p->set (min, max, vr_p->equiv ());
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
543 else if (cond_code == GT_EXPR)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
544 vr_p->set (min, max, vr_p->equiv (), VR_ANTI_RANGE);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
545 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
546 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
547 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
548 else if (cond_code == EQ_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
549 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
550 enum value_range_kind range_kind;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
551
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
552 if (limit_vr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
553 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
554 range_kind = limit_vr->kind ();
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
555 min = limit_vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
556 max = limit_vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
557 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
558 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
559 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
560 range_kind = VR_RANGE;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
561 min = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
562 max = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
563 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
564
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
565 vr_p->update (min, max, range_kind);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
566
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
567 /* When asserting the equality VAR == LIMIT and LIMIT is another
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
568 SSA name, the new range will also inherit the equivalence set
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
569 from LIMIT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
570 if (TREE_CODE (limit) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
571 vr_p->equiv_add (limit, get_value_range (limit), &vrp_equiv_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
572 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
573 else if (cond_code == NE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
574 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
575 /* As described above, when LIMIT's range is an anti-range and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
576 this assertion is an inequality (NE_EXPR), then we cannot
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
577 derive anything from the anti-range. For instance, if
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
578 LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
579 not imply that VAR's range is [0, 0]. So, in the case of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
580 anti-ranges, we just assert the inequality using LIMIT and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
581 not its anti-range.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
582
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
583 If LIMIT_VR is a range, we can only use it to build a new
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
584 anti-range if LIMIT_VR is a single-valued range. For
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
585 instance, if LIMIT_VR is [0, 1], the predicate
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
586 VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
587 Rather, it means that for value 0 VAR should be ~[0, 0]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
588 and for value 1, VAR should be ~[1, 1]. We cannot
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
589 represent these ranges.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
590
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
591 The only situation in which we can build a valid
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
592 anti-range is when LIMIT_VR is a single-valued range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
593 (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
594 build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
595 if (limit_vr
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
596 && limit_vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
597 && compare_values (limit_vr->min (), limit_vr->max ()) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
598 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
599 min = limit_vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
600 max = limit_vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
601 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
602 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
603 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
604 /* In any other case, we cannot use LIMIT's range to build a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
605 valid anti-range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
606 min = max = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
607 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
608
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
609 /* If MIN and MAX cover the whole range for their type, then
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
610 just use the original LIMIT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
611 if (INTEGRAL_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
612 && vrp_val_is_min (min)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
613 && vrp_val_is_max (max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
614 min = max = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
615
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
616 vr_p->set (min, max, vr_p->equiv (), VR_ANTI_RANGE);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
617 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
618 else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
619 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
620 min = TYPE_MIN_VALUE (type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
621
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
622 if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
623 max = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
624 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
625 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
626 /* If LIMIT_VR is of the form [N1, N2], we need to build the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
627 range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
628 LT_EXPR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
629 max = limit_vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
630 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
631
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
632 /* If the maximum value forces us to be out of bounds, simply punt.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
633 It would be pointless to try and do anything more since this
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
634 all should be optimized away above us. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
635 if (cond_code == LT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
636 && compare_values (max, min) == 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
637 vr_p->set_varying (TREE_TYPE (min));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
638 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
639 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
640 /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
641 if (cond_code == LT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
642 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
643 if (TYPE_PRECISION (TREE_TYPE (max)) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
644 && !TYPE_UNSIGNED (TREE_TYPE (max)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
645 max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
646 build_int_cst (TREE_TYPE (max), -1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
647 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
648 max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
649 build_int_cst (TREE_TYPE (max), 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
650 /* Signal to compare_values_warnv this expr doesn't overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
651 if (EXPR_P (max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
652 TREE_NO_WARNING (max) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
653 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
654
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
655 vr_p->update (min, max);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
656 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
657 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
658 else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
659 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
660 max = TYPE_MAX_VALUE (type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
661
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
662 if (limit_vr == NULL || limit_vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
663 min = limit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
664 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
665 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
666 /* If LIMIT_VR is of the form [N1, N2], we need to build the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
667 range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
668 GT_EXPR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
669 min = limit_vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
670 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
671
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
672 /* If the minimum value forces us to be out of bounds, simply punt.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
673 It would be pointless to try and do anything more since this
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
674 all should be optimized away above us. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
675 if (cond_code == GT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
676 && compare_values (min, max) == 0)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
677 vr_p->set_varying (TREE_TYPE (min));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
678 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
679 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
680 /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
681 if (cond_code == GT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
682 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
683 if (TYPE_PRECISION (TREE_TYPE (min)) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
684 && !TYPE_UNSIGNED (TREE_TYPE (min)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
685 min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
686 build_int_cst (TREE_TYPE (min), -1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
687 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
688 min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
689 build_int_cst (TREE_TYPE (min), 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
690 /* Signal to compare_values_warnv this expr doesn't overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
691 if (EXPR_P (min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
692 TREE_NO_WARNING (min) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
693 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
694
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
695 vr_p->update (min, max);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
696 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
697 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
698 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
699 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
700
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
701 /* Finally intersect the new range with what we already know about var. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
702 vr_p->intersect (get_value_range (var));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
703 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
704
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
705 /* Extract value range information from an ASSERT_EXPR EXPR and store
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
706 it in *VR_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
707
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
708 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
709 vr_values::extract_range_from_assert (value_range_equiv *vr_p, tree expr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
710 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
711 tree var = ASSERT_EXPR_VAR (expr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
712 tree cond = ASSERT_EXPR_COND (expr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
713 tree limit, op;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
714 enum tree_code cond_code;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
715 gcc_assert (COMPARISON_CLASS_P (cond));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
716
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
717 /* Find VAR in the ASSERT_EXPR conditional. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
718 if (var == TREE_OPERAND (cond, 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
719 || TREE_CODE (TREE_OPERAND (cond, 0)) == PLUS_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
720 || TREE_CODE (TREE_OPERAND (cond, 0)) == NOP_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
721 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
722 /* If the predicate is of the form VAR COMP LIMIT, then we just
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
723 take LIMIT from the RHS and use the same comparison code. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
724 cond_code = TREE_CODE (cond);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
725 limit = TREE_OPERAND (cond, 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
726 op = TREE_OPERAND (cond, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
727 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
728 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
729 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
730 /* If the predicate is of the form LIMIT COMP VAR, then we need
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
731 to flip around the comparison code to create the proper range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
732 for VAR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
733 cond_code = swap_tree_comparison (TREE_CODE (cond));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
734 limit = TREE_OPERAND (cond, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
735 op = TREE_OPERAND (cond, 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
736 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
737 extract_range_for_var_from_comparison_expr (var, cond_code, op,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
738 limit, vr_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
739 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
740
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
741 /* Extract range information from SSA name VAR and store it in VR. If
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
742 VAR has an interesting range, use it. Otherwise, create the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
743 range [VAR, VAR] and return it. This is useful in situations where
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
744 we may have conditionals testing values of VARYING names. For
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
745 instance,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
746
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
747 x_3 = y_5;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
748 if (x_3 > y_5)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
749 ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
750
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
751 Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
752 always false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
753
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
754 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
755 vr_values::extract_range_from_ssa_name (value_range_equiv *vr, tree var)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
756 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
757 const value_range_equiv *var_vr = get_value_range (var);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
758
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
759 if (!var_vr->varying_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
760 vr->deep_copy (var_vr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
761 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
762 vr->set (var);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
763
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
764 if (!vr->undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
765 vr->equiv_add (var, get_value_range (var), &vrp_equiv_obstack);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
766 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
767
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
768 /* Extract range information from a binary expression OP0 CODE OP1 based on
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
769 the ranges of each of its operands with resulting type EXPR_TYPE.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
770 The resulting range is stored in *VR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
771
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
772 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
773 vr_values::extract_range_from_binary_expr (value_range_equiv *vr,
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
774 enum tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
775 tree expr_type, tree op0, tree op1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
776 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
777 /* Get value ranges for each operand. For constant operands, create
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
778 a new value range with the operand to simplify processing. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
779 value_range vr0, vr1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
780 if (TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
781 vr0 = *(get_value_range (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
782 else if (is_gimple_min_invariant (op0))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
783 vr0.set (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
784 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
785 vr0.set_varying (TREE_TYPE (op0));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
786
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
787 if (TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
788 vr1 = *(get_value_range (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
789 else if (is_gimple_min_invariant (op1))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
790 vr1.set (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
791 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
792 vr1.set_varying (TREE_TYPE (op1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
793
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
794 /* If one argument is varying, we can sometimes still deduce a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
795 range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
796 if (INTEGRAL_TYPE_P (TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
797 && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
798 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
799 if (vr0.varying_p () && !vr1.varying_p ())
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
800 vr0 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
801 else if (vr1.varying_p () && !vr0.varying_p ())
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
802 vr1 = value_range (vrp_val_min (expr_type), vrp_val_max (expr_type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
803 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
804
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
805 range_fold_binary_expr (vr, code, expr_type, &vr0, &vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
806
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
807 /* Set value_range for n in following sequence:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
808 def = __builtin_memchr (arg, 0, sz)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
809 n = def - arg
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
810 Here the range for n can be set to [0, PTRDIFF_MAX - 1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
811
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
812 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
813 && code == POINTER_DIFF_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
814 && TREE_CODE (op0) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
815 && TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
816 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
817 tree op0_ptype = TREE_TYPE (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
818 tree op1_ptype = TREE_TYPE (TREE_TYPE (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
819 gcall *call_stmt = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
820
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
821 if (TYPE_MODE (op0_ptype) == TYPE_MODE (char_type_node)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
822 && TYPE_PRECISION (op0_ptype) == TYPE_PRECISION (char_type_node)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
823 && TYPE_MODE (op1_ptype) == TYPE_MODE (char_type_node)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
824 && TYPE_PRECISION (op1_ptype) == TYPE_PRECISION (char_type_node)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
825 && (call_stmt = dyn_cast<gcall *>(SSA_NAME_DEF_STMT (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
826 && gimple_call_builtin_p (call_stmt, BUILT_IN_MEMCHR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
827 && operand_equal_p (op0, gimple_call_lhs (call_stmt), 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
828 && operand_equal_p (op1, gimple_call_arg (call_stmt, 0), 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
829 && integer_zerop (gimple_call_arg (call_stmt, 1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
830 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
831 tree max = vrp_val_max (ptrdiff_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
832 wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
833 tree range_min = build_zero_cst (expr_type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
834 tree range_max = wide_int_to_tree (expr_type, wmax - 1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
835 vr->set (range_min, range_max);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
836 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
837 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
838 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
839
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
840 /* Try harder for PLUS and MINUS if the range of one operand is symbolic
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
841 and based on the other operand, for example if it was deduced from a
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
842 symbolic comparison. When a bound of the range of the first operand
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
843 is invariant, we set the corresponding bound of the new range to INF
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
844 in order to avoid recursing on the range of the second operand. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
845 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
846 && (code == PLUS_EXPR || code == MINUS_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
847 && TREE_CODE (op1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
848 && vr0.kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
849 && symbolic_range_based_on_p (&vr0, op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
850 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
851 const bool minus_p = (code == MINUS_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
852 value_range n_vr1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
853
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
854 /* Try with VR0 and [-INF, OP1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
855 if (is_gimple_min_invariant (minus_p ? vr0.max () : vr0.min ()))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
856 n_vr1.set (vrp_val_min (expr_type), op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
857
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
858 /* Try with VR0 and [OP1, +INF]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
859 else if (is_gimple_min_invariant (minus_p ? vr0.min () : vr0.max ()))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
860 n_vr1.set (op1, vrp_val_max (expr_type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
861
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
862 /* Try with VR0 and [OP1, OP1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
863 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
864 n_vr1.set (op1, op1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
865
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
866 range_fold_binary_expr (vr, code, expr_type, &vr0, &n_vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
867 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
868
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
869 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
870 && (code == PLUS_EXPR || code == MINUS_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
871 && TREE_CODE (op0) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
872 && vr1.kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
873 && symbolic_range_based_on_p (&vr1, op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
874 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
875 const bool minus_p = (code == MINUS_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
876 value_range n_vr0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
877
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
878 /* Try with [-INF, OP0] and VR1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
879 if (is_gimple_min_invariant (minus_p ? vr1.max () : vr1.min ()))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
880 n_vr0.set (vrp_val_min (expr_type), op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
881
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
882 /* Try with [OP0, +INF] and VR1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
883 else if (is_gimple_min_invariant (minus_p ? vr1.min (): vr1.max ()))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
884 n_vr0.set (op0, vrp_val_max (expr_type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
885
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
886 /* Try with [OP0, OP0] and VR1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
887 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
888 n_vr0.set (op0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
889
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
890 range_fold_binary_expr (vr, code, expr_type, &n_vr0, &vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
891 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
892
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
893 /* If we didn't derive a range for MINUS_EXPR, and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
894 op1's range is ~[op0,op0] or vice-versa, then we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
895 can derive a non-null range. This happens often for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
896 pointer subtraction. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
897 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
898 && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
899 && TREE_CODE (op0) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
900 && ((vr0.kind () == VR_ANTI_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
901 && vr0.min () == op1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
902 && vr0.min () == vr0.max ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
903 || (vr1.kind () == VR_ANTI_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
904 && vr1.min () == op0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
905 && vr1.min () == vr1.max ())))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
906 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
907 vr->set_nonzero (expr_type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
908 vr->equiv_clear ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
909 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
910 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
911
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
912 /* Extract range information from a unary expression CODE OP0 based on
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
913 the range of its operand with resulting type TYPE.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
914 The resulting range is stored in *VR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
915
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
916 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
917 vr_values::extract_range_from_unary_expr (value_range_equiv *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
918 enum tree_code code,
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
919 tree type, tree op0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
920 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
921 value_range vr0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
922
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
923 /* Get value ranges for the operand. For constant operands, create
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
924 a new value range with the operand to simplify processing. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
925 if (TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
926 vr0 = *(get_value_range (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
927 else if (is_gimple_min_invariant (op0))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
928 vr0.set (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
929 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
930 vr0.set_varying (type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
931
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
932 range_fold_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
933 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
934
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
935
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
936 /* Extract range information from a conditional expression STMT based on
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
937 the ranges of each of its operands and the expression code. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
938
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
939 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
940 vr_values::extract_range_from_cond_expr (value_range_equiv *vr, gassign *stmt)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
941 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
942 /* Get value ranges for each operand. For constant operands, create
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
943 a new value range with the operand to simplify processing. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
944 tree op0 = gimple_assign_rhs2 (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
945 value_range_equiv tem0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
946 const value_range_equiv *vr0 = &tem0;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
947 if (TREE_CODE (op0) == SSA_NAME)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
948 vr0 = get_value_range (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
949 else if (is_gimple_min_invariant (op0))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
950 tem0.set (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
951 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
952 tem0.set_varying (TREE_TYPE (op0));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
953
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
954 tree op1 = gimple_assign_rhs3 (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
955 value_range_equiv tem1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
956 const value_range_equiv *vr1 = &tem1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
957 if (TREE_CODE (op1) == SSA_NAME)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
958 vr1 = get_value_range (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
959 else if (is_gimple_min_invariant (op1))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
960 tem1.set (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
961 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
962 tem1.set_varying (TREE_TYPE (op1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
963
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
964 /* The resulting value range is the union of the operand ranges */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
965 vr->deep_copy (vr0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
966 vr->union_ (vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
967 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
968
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
969
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
970 /* Extract range information from a comparison expression EXPR based
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
971 on the range of its operand and the expression code. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
972
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
973 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
974 vr_values::extract_range_from_comparison (value_range_equiv *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
975 enum tree_code code,
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
976 tree type, tree op0, tree op1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
977 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
978 bool sop;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
979 tree val;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
980
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
981 val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
982 NULL);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
983 if (val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
984 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
985 /* Since this expression was found on the RHS of an assignment,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
986 its type may be different from _Bool. Convert VAL to EXPR's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
987 type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
988 val = fold_convert (type, val);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
989 if (is_gimple_min_invariant (val))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
990 vr->set (val);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
991 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
992 vr->update (val, val);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
993 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
994 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
995 /* The result of a comparison is always true or false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
996 set_value_range_to_truthvalue (vr, type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
997 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
998
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
999 /* Helper function for simplify_internal_call_using_ranges and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1000 extract_range_basic. Return true if OP0 SUBCODE OP1 for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1001 SUBCODE {PLUS,MINUS,MULT}_EXPR is known to never overflow or
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1002 always overflow. Set *OVF to true if it is known to always
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1003 overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1004
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1005 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1006 vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1007 tree op0, tree op1, bool *ovf)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1008 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1009 value_range vr0, vr1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1010 if (TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1011 vr0 = *get_value_range (op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1012 else if (TREE_CODE (op0) == INTEGER_CST)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1013 vr0.set (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1014 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1015 vr0.set_varying (TREE_TYPE (op0));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1016
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1017 if (TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1018 vr1 = *get_value_range (op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1019 else if (TREE_CODE (op1) == INTEGER_CST)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1020 vr1.set (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1021 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1022 vr1.set_varying (TREE_TYPE (op1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1023
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1024 tree vr0min = vr0.min (), vr0max = vr0.max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1025 tree vr1min = vr1.min (), vr1max = vr1.max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1026 if (!range_int_cst_p (&vr0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1027 || TREE_OVERFLOW (vr0min)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1028 || TREE_OVERFLOW (vr0max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1029 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1030 vr0min = vrp_val_min (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1031 vr0max = vrp_val_max (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1032 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1033 if (!range_int_cst_p (&vr1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1034 || TREE_OVERFLOW (vr1min)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1035 || TREE_OVERFLOW (vr1max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1036 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1037 vr1min = vrp_val_min (TREE_TYPE (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1038 vr1max = vrp_val_max (TREE_TYPE (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1039 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1040 *ovf = arith_overflowed_p (subcode, type, vr0min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1041 subcode == MINUS_EXPR ? vr1max : vr1min);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1042 if (arith_overflowed_p (subcode, type, vr0max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1043 subcode == MINUS_EXPR ? vr1min : vr1max) != *ovf)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1044 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1045 if (subcode == MULT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1046 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1047 if (arith_overflowed_p (subcode, type, vr0min, vr1max) != *ovf
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1048 || arith_overflowed_p (subcode, type, vr0max, vr1min) != *ovf)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1049 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1050 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1051 if (*ovf)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1052 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1053 /* So far we found that there is an overflow on the boundaries.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1054 That doesn't prove that there is an overflow even for all values
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1055 in between the boundaries. For that compute widest_int range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1056 of the result and see if it doesn't overlap the range of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1057 type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1058 widest_int wmin, wmax;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1059 widest_int w[4];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1060 int i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1061 w[0] = wi::to_widest (vr0min);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1062 w[1] = wi::to_widest (vr0max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1063 w[2] = wi::to_widest (vr1min);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1064 w[3] = wi::to_widest (vr1max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1065 for (i = 0; i < 4; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1066 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1067 widest_int wt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1068 switch (subcode)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1069 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1070 case PLUS_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1071 wt = wi::add (w[i & 1], w[2 + (i & 2) / 2]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1072 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1073 case MINUS_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1074 wt = wi::sub (w[i & 1], w[2 + (i & 2) / 2]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1075 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1076 case MULT_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1077 wt = wi::mul (w[i & 1], w[2 + (i & 2) / 2]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1078 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1079 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1080 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1081 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1082 if (i == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1083 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1084 wmin = wt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1085 wmax = wt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1086 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1087 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1088 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1089 wmin = wi::smin (wmin, wt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1090 wmax = wi::smax (wmax, wt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1091 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1092 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1093 /* The result of op0 CODE op1 is known to be in range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1094 [wmin, wmax]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1095 widest_int wtmin = wi::to_widest (vrp_val_min (type));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1096 widest_int wtmax = wi::to_widest (vrp_val_max (type));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1097 /* If all values in [wmin, wmax] are smaller than
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1098 [wtmin, wtmax] or all are larger than [wtmin, wtmax],
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1099 the arithmetic operation will always overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1100 if (wmax < wtmin || wmin > wtmax)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1101 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1102 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1103 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1104 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1105 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1106
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1107 /* Try to derive a nonnegative or nonzero range out of STMT relying
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1108 primarily on generic routines in fold in conjunction with range data.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1109 Store the result in *VR */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1110
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1111 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1112 vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1113 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1114 bool sop;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1115 tree type = gimple_expr_type (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1116
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1117 if (is_gimple_call (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1118 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1119 tree arg;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1120 int mini, maxi, zerov = 0, prec;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1121 enum tree_code subcode = ERROR_MARK;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1122 combined_fn cfn = gimple_call_combined_fn (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1123 scalar_int_mode mode;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1124
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1125 switch (cfn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1126 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1127 case CFN_BUILT_IN_CONSTANT_P:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1128 /* Resolve calls to __builtin_constant_p after inlining. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1129 if (cfun->after_inlining)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1130 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1131 vr->set_zero (type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1132 vr->equiv_clear ();
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1133 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1134 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1135 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1136 /* Both __builtin_ffs* and __builtin_popcount return
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1137 [0, prec]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1138 CASE_CFN_FFS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1139 CASE_CFN_POPCOUNT:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1140 arg = gimple_call_arg (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1141 prec = TYPE_PRECISION (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1142 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1143 maxi = prec;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1144 if (TREE_CODE (arg) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1145 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1146 const value_range_equiv *vr0 = get_value_range (arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1147 /* If arg is non-zero, then ffs or popcount are non-zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1148 if (range_includes_zero_p (vr0) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1149 mini = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1150 /* If some high bits are known to be zero,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1151 we can decrease the maximum. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1152 if (vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1153 && TREE_CODE (vr0->max ()) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1154 && !operand_less_p (vr0->min (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1155 build_zero_cst (TREE_TYPE (vr0->min ()))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1156 maxi = tree_floor_log2 (vr0->max ()) + 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1157 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1158 goto bitop_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1159 /* __builtin_parity* returns [0, 1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1160 CASE_CFN_PARITY:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1161 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1162 maxi = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1163 goto bitop_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1164 /* __builtin_c[lt]z* return [0, prec-1], except for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1165 when the argument is 0, but that is undefined behavior.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1166 On many targets where the CLZ RTL or optab value is defined
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1167 for 0 the value is prec, so include that in the range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1168 by default. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1169 CASE_CFN_CLZ:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1170 arg = gimple_call_arg (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1171 prec = TYPE_PRECISION (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1172 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1173 maxi = prec;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1174 mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1175 if (optab_handler (clz_optab, mode) != CODE_FOR_nothing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1176 && CLZ_DEFINED_VALUE_AT_ZERO (mode, zerov)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1177 /* Handle only the single common value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1178 && zerov != prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1179 /* Magic value to give up, unless vr0 proves
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1180 arg is non-zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1181 mini = -2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1182 if (TREE_CODE (arg) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1183 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1184 const value_range_equiv *vr0 = get_value_range (arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1185 /* From clz of VR_RANGE minimum we can compute
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1186 result maximum. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1187 if (vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1188 && TREE_CODE (vr0->min ()) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1189 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1190 maxi = prec - 1 - tree_floor_log2 (vr0->min ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1191 if (maxi != prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1192 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1193 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1194 else if (vr0->kind () == VR_ANTI_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1195 && integer_zerop (vr0->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1196 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1197 maxi = prec - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1198 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1199 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1200 if (mini == -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1201 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1202 /* From clz of VR_RANGE maximum we can compute
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1203 result minimum. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1204 if (vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1205 && TREE_CODE (vr0->max ()) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1206 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1207 mini = prec - 1 - tree_floor_log2 (vr0->max ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1208 if (mini == prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1209 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1210 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1211 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1212 if (mini == -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1213 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1214 goto bitop_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1215 /* __builtin_ctz* return [0, prec-1], except for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1216 when the argument is 0, but that is undefined behavior.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1217 If there is a ctz optab for this mode and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1218 CTZ_DEFINED_VALUE_AT_ZERO, include that in the range,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1219 otherwise just assume 0 won't be seen. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1220 CASE_CFN_CTZ:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1221 arg = gimple_call_arg (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1222 prec = TYPE_PRECISION (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1223 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1224 maxi = prec - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1225 mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1226 if (optab_handler (ctz_optab, mode) != CODE_FOR_nothing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1227 && CTZ_DEFINED_VALUE_AT_ZERO (mode, zerov))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1228 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1229 /* Handle only the two common values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1230 if (zerov == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1231 mini = -1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1232 else if (zerov == prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1233 maxi = prec;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1234 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1235 /* Magic value to give up, unless vr0 proves
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1236 arg is non-zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1237 mini = -2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1238 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1239 if (TREE_CODE (arg) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1240 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1241 const value_range_equiv *vr0 = get_value_range (arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1242 /* If arg is non-zero, then use [0, prec - 1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1243 if ((vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1244 && integer_nonzerop (vr0->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1245 || (vr0->kind () == VR_ANTI_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1246 && integer_zerop (vr0->min ())))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1247 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1248 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1249 maxi = prec - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1250 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1251 /* If some high bits are known to be zero,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1252 we can decrease the result maximum. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1253 if (vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1254 && TREE_CODE (vr0->max ()) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1255 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1256 maxi = tree_floor_log2 (vr0->max ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1257 /* For vr0 [0, 0] give up. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1258 if (maxi == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1259 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1260 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1261 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1262 if (mini == -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1263 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1264 goto bitop_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1265 /* __builtin_clrsb* returns [0, prec-1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1266 CASE_CFN_CLRSB:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1267 arg = gimple_call_arg (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1268 prec = TYPE_PRECISION (TREE_TYPE (arg));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1269 mini = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1270 maxi = prec - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1271 goto bitop_builtin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1272 bitop_builtin:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1273 vr->set (build_int_cst (type, mini), build_int_cst (type, maxi));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1274 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1275 case CFN_UBSAN_CHECK_ADD:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1276 subcode = PLUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1277 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1278 case CFN_UBSAN_CHECK_SUB:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1279 subcode = MINUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1280 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1281 case CFN_UBSAN_CHECK_MUL:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1282 subcode = MULT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1283 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1284 case CFN_GOACC_DIM_SIZE:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1285 case CFN_GOACC_DIM_POS:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1286 /* Optimizing these two internal functions helps the loop
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1287 optimizer eliminate outer comparisons. Size is [1,N]
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1288 and pos is [0,N-1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1289 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1290 bool is_pos = cfn == CFN_GOACC_DIM_POS;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1291 int axis = oacc_get_ifn_dim_arg (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1292 int size = oacc_get_fn_dim_size (current_function_decl, axis);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1293
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1294 if (!size)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1295 /* If it's dynamic, the backend might know a hardware
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1296 limitation. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1297 size = targetm.goacc.dim_limit (axis);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1298
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1299 tree type = TREE_TYPE (gimple_call_lhs (stmt));
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1300 vr->set(build_int_cst (type, is_pos ? 0 : 1),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1301 size
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1302 ? build_int_cst (type, size - is_pos) : vrp_val_max (type));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1303 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1304 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1305 case CFN_BUILT_IN_STRLEN:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1306 if (tree lhs = gimple_call_lhs (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1307 if (ptrdiff_type_node
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1308 && (TYPE_PRECISION (ptrdiff_type_node)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1309 == TYPE_PRECISION (TREE_TYPE (lhs))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1310 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1311 tree type = TREE_TYPE (lhs);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1312 tree max = vrp_val_max (ptrdiff_type_node);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1313 wide_int wmax = wi::to_wide (max, TYPE_PRECISION (TREE_TYPE (max)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1314 tree range_min = build_zero_cst (type);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1315 /* To account for the terminating NUL, the maximum length
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1316 is one less than the maximum array size, which in turn
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1317 is one less than PTRDIFF_MAX (or SIZE_MAX where it's
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1318 smaller than the former type).
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1319 FIXME: Use max_object_size() - 1 here. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1320 tree range_max = wide_int_to_tree (type, wmax - 2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1321 vr->set (range_min, range_max);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1322 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1323 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1324 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1325 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1326 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1327 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1328 if (subcode != ERROR_MARK)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1329 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1330 bool saved_flag_wrapv = flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1331 /* Pretend the arithmetics is wrapping. If there is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1332 any overflow, we'll complain, but will actually do
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1333 wrapping operation. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1334 flag_wrapv = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1335 extract_range_from_binary_expr (vr, subcode, type,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1336 gimple_call_arg (stmt, 0),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1337 gimple_call_arg (stmt, 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1338 flag_wrapv = saved_flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1339
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1340 /* If for both arguments vrp_valueize returned non-NULL,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1341 this should have been already folded and if not, it
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1342 wasn't folded because of overflow. Avoid removing the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1343 UBSAN_CHECK_* calls in that case. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1344 if (vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1345 && (vr->min () == vr->max ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1346 || operand_equal_p (vr->min (), vr->max (), 0)))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1347 vr->set_varying (vr->type ());
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1348 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1349 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1350 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1351 /* Handle extraction of the two results (result of arithmetics and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1352 a flag whether arithmetics overflowed) from {ADD,SUB,MUL}_OVERFLOW
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1353 internal function. Similarly from ATOMIC_COMPARE_EXCHANGE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1354 else if (is_gimple_assign (stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1355 && (gimple_assign_rhs_code (stmt) == REALPART_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1356 || gimple_assign_rhs_code (stmt) == IMAGPART_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1357 && INTEGRAL_TYPE_P (type))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1358 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1359 enum tree_code code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1360 tree op = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1361 if (TREE_CODE (op) == code && TREE_CODE (TREE_OPERAND (op, 0)) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1362 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1363 gimple *g = SSA_NAME_DEF_STMT (TREE_OPERAND (op, 0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1364 if (is_gimple_call (g) && gimple_call_internal_p (g))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1365 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1366 enum tree_code subcode = ERROR_MARK;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1367 switch (gimple_call_internal_fn (g))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1368 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1369 case IFN_ADD_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1370 subcode = PLUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1371 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1372 case IFN_SUB_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1373 subcode = MINUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1374 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1375 case IFN_MUL_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1376 subcode = MULT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1377 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1378 case IFN_ATOMIC_COMPARE_EXCHANGE:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1379 if (code == IMAGPART_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1380 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1381 /* This is the boolean return value whether compare and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1382 exchange changed anything or not. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1383 vr->set (build_int_cst (type, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1384 build_int_cst (type, 1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1385 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1386 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1387 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1388 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1389 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1390 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1391 if (subcode != ERROR_MARK)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1392 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1393 tree op0 = gimple_call_arg (g, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1394 tree op1 = gimple_call_arg (g, 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1395 if (code == IMAGPART_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1396 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1397 bool ovf = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1398 if (check_for_binary_op_overflow (subcode, type,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1399 op0, op1, &ovf))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1400 vr->set (build_int_cst (type, ovf));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1401 else if (TYPE_PRECISION (type) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1402 && !TYPE_UNSIGNED (type))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1403 vr->set_varying (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1404 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1405 vr->set (build_int_cst (type, 0),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1406 build_int_cst (type, 1));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1407 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1408 else if (types_compatible_p (type, TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1409 && types_compatible_p (type, TREE_TYPE (op1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1410 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1411 bool saved_flag_wrapv = flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1412 /* Pretend the arithmetics is wrapping. If there is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1413 any overflow, IMAGPART_EXPR will be set. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1414 flag_wrapv = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1415 extract_range_from_binary_expr (vr, subcode, type,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1416 op0, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1417 flag_wrapv = saved_flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1418 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1419 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1420 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1421 value_range_equiv vr0, vr1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1422 bool saved_flag_wrapv = flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1423 /* Pretend the arithmetics is wrapping. If there is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1424 any overflow, IMAGPART_EXPR will be set. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1425 flag_wrapv = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1426 extract_range_from_unary_expr (&vr0, NOP_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1427 type, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1428 extract_range_from_unary_expr (&vr1, NOP_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1429 type, op1);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1430 range_fold_binary_expr (vr, subcode, type, &vr0, &vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1431 flag_wrapv = saved_flag_wrapv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1432 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1433 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1434 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1435 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1436 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1437 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1438 if (INTEGRAL_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1439 && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1440 set_value_range_to_nonnegative (vr, type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1441 else if (vrp_stmt_computes_nonzero (stmt))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1442 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1443 vr->set_nonzero (type);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1444 vr->equiv_clear ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1445 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1446 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1447 vr->set_varying (type);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1448 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1449
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1450
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1451 /* Try to compute a useful range out of assignment STMT and store it
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1452 in *VR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1453
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1454 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1455 vr_values::extract_range_from_assignment (value_range_equiv *vr, gassign *stmt)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1456 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1457 enum tree_code code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1458
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1459 if (code == ASSERT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1460 extract_range_from_assert (vr, gimple_assign_rhs1 (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1461 else if (code == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1462 extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1463 else if (TREE_CODE_CLASS (code) == tcc_binary)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1464 extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1465 gimple_expr_type (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1466 gimple_assign_rhs1 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1467 gimple_assign_rhs2 (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1468 else if (TREE_CODE_CLASS (code) == tcc_unary)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1469 extract_range_from_unary_expr (vr, gimple_assign_rhs_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1470 gimple_expr_type (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1471 gimple_assign_rhs1 (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1472 else if (code == COND_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1473 extract_range_from_cond_expr (vr, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1474 else if (TREE_CODE_CLASS (code) == tcc_comparison)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1475 extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1476 gimple_expr_type (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1477 gimple_assign_rhs1 (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1478 gimple_assign_rhs2 (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1479 else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1480 && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1481 vr->set (gimple_assign_rhs1 (stmt));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1482 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1483 vr->set_varying (TREE_TYPE (gimple_assign_lhs (stmt)));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1484
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1485 if (vr->varying_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1486 extract_range_basic (vr, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1487 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1488
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1489 /* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1490
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1491 - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1492 all the values in the ranges.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1493
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1494 - Return BOOLEAN_FALSE_NODE if the comparison always returns false.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1495
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1496 - Return NULL_TREE if it is not always possible to determine the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1497 value of the comparison.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1498
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1499 Also set *STRICT_OVERFLOW_P to indicate whether comparision evaluation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1500 assumed signed overflow is undefined. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1501
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1502
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1503 static tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1504 compare_ranges (enum tree_code comp, const value_range_equiv *vr0,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1505 const value_range_equiv *vr1, bool *strict_overflow_p)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1506 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1507 /* VARYING or UNDEFINED ranges cannot be compared. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1508 if (vr0->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1509 || vr0->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1510 || vr1->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1511 || vr1->undefined_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1512 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1513
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1514 /* Anti-ranges need to be handled separately. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1515 if (vr0->kind () == VR_ANTI_RANGE || vr1->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1516 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1517 /* If both are anti-ranges, then we cannot compute any
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1518 comparison. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1519 if (vr0->kind () == VR_ANTI_RANGE && vr1->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1520 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1521
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1522 /* These comparisons are never statically computable. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1523 if (comp == GT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1524 || comp == GE_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1525 || comp == LT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1526 || comp == LE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1527 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1528
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1529 /* Equality can be computed only between a range and an
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1530 anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1531 if (vr0->kind () == VR_RANGE)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1532 /* To simplify processing, make VR0 the anti-range. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1533 std::swap (vr0, vr1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1534
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1535 gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1536
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1537 if (compare_values_warnv (vr0->min (), vr1->min (), strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1538 && compare_values_warnv (vr0->max (), vr1->max (), strict_overflow_p) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1539 return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1540
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1541 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1542 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1543
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1544 /* Simplify processing. If COMP is GT_EXPR or GE_EXPR, switch the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1545 operands around and change the comparison code. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1546 if (comp == GT_EXPR || comp == GE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1547 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1548 comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1549 std::swap (vr0, vr1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1550 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1551
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1552 if (comp == EQ_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1553 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1554 /* Equality may only be computed if both ranges represent
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1555 exactly one value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1556 if (compare_values_warnv (vr0->min (), vr0->max (), strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1557 && compare_values_warnv (vr1->min (), vr1->max (), strict_overflow_p) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1558 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1559 int cmp_min = compare_values_warnv (vr0->min (), vr1->min (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1560 strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1561 int cmp_max = compare_values_warnv (vr0->max (), vr1->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1562 strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1563 if (cmp_min == 0 && cmp_max == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1564 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1565 else if (cmp_min != -2 && cmp_max != -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1566 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1567 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1568 /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1569 else if (compare_values_warnv (vr0->min (), vr1->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1570 strict_overflow_p) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1571 || compare_values_warnv (vr1->min (), vr0->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1572 strict_overflow_p) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1573 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1574
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1575 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1576 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1577 else if (comp == NE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1578 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1579 int cmp1, cmp2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1580
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1581 /* If VR0 is completely to the left or completely to the right
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1582 of VR1, they are always different. Notice that we need to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1583 make sure that both comparisons yield similar results to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1584 avoid comparing values that cannot be compared at
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1585 compile-time. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1586 cmp1 = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1587 cmp2 = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1588 if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1589 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1590
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1591 /* If VR0 and VR1 represent a single value and are identical,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1592 return false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1593 else if (compare_values_warnv (vr0->min (), vr0->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1594 strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1595 && compare_values_warnv (vr1->min (), vr1->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1596 strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1597 && compare_values_warnv (vr0->min (), vr1->min (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1598 strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1599 && compare_values_warnv (vr0->max (), vr1->max (),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1600 strict_overflow_p) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1601 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1602
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1603 /* Otherwise, they may or may not be different. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1604 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1605 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1606 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1607 else if (comp == LT_EXPR || comp == LE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1608 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1609 int tst;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1610
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1611 /* If VR0 is to the left of VR1, return true. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1612 tst = compare_values_warnv (vr0->max (), vr1->min (), strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1613 if ((comp == LT_EXPR && tst == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1614 || (comp == LE_EXPR && (tst == -1 || tst == 0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1615 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1616
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1617 /* If VR0 is to the right of VR1, return false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1618 tst = compare_values_warnv (vr0->min (), vr1->max (), strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1619 if ((comp == LT_EXPR && (tst == 0 || tst == 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1620 || (comp == LE_EXPR && tst == 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1621 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1622
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1623 /* Otherwise, we don't know. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1624 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1625 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1626
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1627 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1628 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1629
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1630 /* Given a value range VR, a value VAL and a comparison code COMP, return
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1631 BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1632 values in VR. Return BOOLEAN_FALSE_NODE if the comparison
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1633 always returns false. Return NULL_TREE if it is not always
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1634 possible to determine the value of the comparison. Also set
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1635 *STRICT_OVERFLOW_P to indicate whether comparision evaluation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1636 assumed signed overflow is undefined. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1637
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1638 static tree
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1639 compare_range_with_value (enum tree_code comp, const value_range_equiv *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1640 tree val, bool *strict_overflow_p)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1641 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1642 if (vr->varying_p () || vr->undefined_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1643 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1644
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1645 /* Anti-ranges need to be handled separately. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1646 if (vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1647 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1648 /* For anti-ranges, the only predicates that we can compute at
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1649 compile time are equality and inequality. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1650 if (comp == GT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1651 || comp == GE_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1652 || comp == LT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1653 || comp == LE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1654 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1655
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1656 /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1657 if (!vr->may_contain_p (val))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1658 return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1659
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1660 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1661 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1662
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1663 if (comp == EQ_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1664 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1665 /* EQ_EXPR may only be computed if VR represents exactly
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1666 one value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1667 if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1668 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1669 int cmp = compare_values_warnv (vr->min (), val, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1670 if (cmp == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1671 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1672 else if (cmp == -1 || cmp == 1 || cmp == 2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1673 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1674 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1675 else if (compare_values_warnv (val, vr->min (), strict_overflow_p) == -1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1676 || compare_values_warnv (vr->max (), val, strict_overflow_p) == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1677 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1678
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1679 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1680 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1681 else if (comp == NE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1682 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1683 /* If VAL is not inside VR, then they are always different. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1684 if (compare_values_warnv (vr->max (), val, strict_overflow_p) == -1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1685 || compare_values_warnv (vr->min (), val, strict_overflow_p) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1686 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1687
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1688 /* If VR represents exactly one value equal to VAL, then return
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1689 false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1690 if (compare_values_warnv (vr->min (), vr->max (), strict_overflow_p) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1691 && compare_values_warnv (vr->min (), val, strict_overflow_p) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1692 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1693
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1694 /* Otherwise, they may or may not be different. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1695 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1696 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1697 else if (comp == LT_EXPR || comp == LE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1698 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1699 int tst;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1700
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1701 /* If VR is to the left of VAL, return true. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1702 tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1703 if ((comp == LT_EXPR && tst == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1704 || (comp == LE_EXPR && (tst == -1 || tst == 0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1705 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1706
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1707 /* If VR is to the right of VAL, return false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1708 tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1709 if ((comp == LT_EXPR && (tst == 0 || tst == 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1710 || (comp == LE_EXPR && tst == 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1711 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1712
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1713 /* Otherwise, we don't know. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1714 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1715 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1716 else if (comp == GT_EXPR || comp == GE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1717 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1718 int tst;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1719
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1720 /* If VR is to the right of VAL, return true. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1721 tst = compare_values_warnv (vr->min (), val, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1722 if ((comp == GT_EXPR && tst == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1723 || (comp == GE_EXPR && (tst == 0 || tst == 1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1724 return boolean_true_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1725
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1726 /* If VR is to the left of VAL, return false. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1727 tst = compare_values_warnv (vr->max (), val, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1728 if ((comp == GT_EXPR && (tst == -1 || tst == 0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1729 || (comp == GE_EXPR && tst == -1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1730 return boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1731
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1732 /* Otherwise, we don't know. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1733 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1734 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1735
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1736 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1737 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1738 /* Given a range VR, a LOOP and a variable VAR, determine whether it
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1739 would be profitable to adjust VR using scalar evolution information
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1740 for VAR. If so, update VR with the new limits. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1741
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1742 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1743 vr_values::adjust_range_with_scev (value_range_equiv *vr, class loop *loop,
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1744 gimple *stmt, tree var)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1745 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1746 tree init, step, chrec, tmin, tmax, min, max, type, tem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1747 enum ev_direction dir;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1748
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1749 /* TODO. Don't adjust anti-ranges. An anti-range may provide
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1750 better opportunities than a regular range, but I'm not sure. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1751 if (vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1752 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1753
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1754 chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1755
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1756 /* Like in PR19590, scev can return a constant function. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1757 if (is_gimple_min_invariant (chrec))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1758 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1759 vr->set (chrec);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1760 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1761 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1762
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1763 if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1764 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1765
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1766 init = initial_condition_in_loop_num (chrec, loop->num);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1767 tem = op_with_constant_singleton_value_range (init);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1768 if (tem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1769 init = tem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1770 step = evolution_part_in_loop_num (chrec, loop->num);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1771 tem = op_with_constant_singleton_value_range (step);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1772 if (tem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1773 step = tem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1774
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1775 /* If STEP is symbolic, we can't know whether INIT will be the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1776 minimum or maximum value in the range. Also, unless INIT is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1777 a simple expression, compare_values and possibly other functions
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1778 in tree-vrp won't be able to handle it. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1779 if (step == NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1780 || !is_gimple_min_invariant (step)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1781 || !valid_value_p (init))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1782 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1783
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1784 dir = scev_direction (chrec);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1785 if (/* Do not adjust ranges if we do not know whether the iv increases
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1786 or decreases, ... */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1787 dir == EV_DIR_UNKNOWN
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1788 /* ... or if it may wrap. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1789 || scev_probably_wraps_p (NULL_TREE, init, step, stmt,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1790 get_chrec_loop (chrec), true))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1791 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1792
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1793 type = TREE_TYPE (var);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1794 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1795 tmin = lower_bound_in_type (type, type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1796 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1797 tmin = TYPE_MIN_VALUE (type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1798 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1799 tmax = upper_bound_in_type (type, type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1800 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1801 tmax = TYPE_MAX_VALUE (type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1802
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1803 /* Try to use estimated number of iterations for the loop to constrain the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1804 final value in the evolution. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1805 if (TREE_CODE (step) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1806 && is_gimple_val (init)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1807 && (TREE_CODE (init) != SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1808 || get_value_range (init)->kind () == VR_RANGE))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1809 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1810 widest_int nit;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1811
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1812 /* We are only entering here for loop header PHI nodes, so using
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1813 the number of latch executions is the correct thing to use. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1814 if (max_loop_iterations (loop, &nit))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1815 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1816 signop sgn = TYPE_SIGN (TREE_TYPE (step));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1817 wi::overflow_type overflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1818
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1819 widest_int wtmp = wi::mul (wi::to_widest (step), nit, sgn,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1820 &overflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1821 /* If the multiplication overflowed we can't do a meaningful
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1822 adjustment. Likewise if the result doesn't fit in the type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1823 of the induction variable. For a signed type we have to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1824 check whether the result has the expected signedness which
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1825 is that of the step as number of iterations is unsigned. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1826 if (!overflow
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1827 && wi::fits_to_tree_p (wtmp, TREE_TYPE (init))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1828 && (sgn == UNSIGNED
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1829 || wi::gts_p (wtmp, 0) == wi::gts_p (wi::to_wide (step), 0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1830 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1831 value_range_equiv maxvr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1832 tem = wide_int_to_tree (TREE_TYPE (init), wtmp);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1833 extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1834 TREE_TYPE (init), init, tem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1835 /* Likewise if the addition did. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1836 if (maxvr.kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1837 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1838 value_range initvr;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1839
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1840 if (TREE_CODE (init) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1841 initvr = *(get_value_range (init));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1842 else if (is_gimple_min_invariant (init))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1843 initvr.set (init);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1844 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1845 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1846
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1847 /* Check if init + nit * step overflows. Though we checked
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1848 scev {init, step}_loop doesn't wrap, it is not enough
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1849 because the loop may exit immediately. Overflow could
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1850 happen in the plus expression in this case. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1851 if ((dir == EV_DIR_DECREASES
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1852 && compare_values (maxvr.min (), initvr.min ()) != -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1853 || (dir == EV_DIR_GROWS
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1854 && compare_values (maxvr.max (), initvr.max ()) != 1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1855 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1856
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1857 tmin = maxvr.min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1858 tmax = maxvr.max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1859 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1860 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1861 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1862 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1863
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1864 if (vr->varying_p () || vr->undefined_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1865 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1866 min = tmin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1867 max = tmax;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1868
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1869 /* For VARYING or UNDEFINED ranges, just about anything we get
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1870 from scalar evolutions should be better. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1871
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1872 if (dir == EV_DIR_DECREASES)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1873 max = init;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1874 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1875 min = init;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1876 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1877 else if (vr->kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1878 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1879 min = vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1880 max = vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1881
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1882 if (dir == EV_DIR_DECREASES)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1883 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1884 /* INIT is the maximum value. If INIT is lower than VR->MAX ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1885 but no smaller than VR->MIN (), set VR->MAX () to INIT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1886 if (compare_values (init, max) == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1887 max = init;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1888
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1889 /* According to the loop information, the variable does not
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1890 overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1891 if (compare_values (min, tmin) == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1892 min = tmin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1893
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1894 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1895 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1896 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1897 /* If INIT is bigger than VR->MIN (), set VR->MIN () to INIT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1898 if (compare_values (init, min) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1899 min = init;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1900
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1901 if (compare_values (tmax, max) == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1902 max = tmax;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1903 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1904 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1905 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1906 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1907
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1908 /* If we just created an invalid range with the minimum
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1909 greater than the maximum, we fail conservatively.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1910 This should happen only in unreachable
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1911 parts of code, or for invalid programs. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1912 if (compare_values (min, max) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1913 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1914
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1915 /* Even for valid range info, sometimes overflow flag will leak in.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1916 As GIMPLE IL should have no constants with TREE_OVERFLOW set, we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1917 drop them. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1918 if (TREE_OVERFLOW_P (min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1919 min = drop_tree_overflow (min);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1920 if (TREE_OVERFLOW_P (max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1921 max = drop_tree_overflow (max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1922
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1923 vr->update (min, max);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1924 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1925
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1926 /* Dump value ranges of all SSA_NAMEs to FILE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1927
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1928 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1929 vr_values::dump_all_value_ranges (FILE *file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1930 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1931 size_t i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1932
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1933 for (i = 0; i < num_vr_values; i++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1934 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1935 if (vr_value[i])
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1936 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1937 print_generic_expr (file, ssa_name (i));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1938 fprintf (file, ": ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1939 dump_value_range (file, vr_value[i]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1940 fprintf (file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1941 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1942 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1943
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1944 fprintf (file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1945 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1946
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1947 /* Initialize VRP lattice. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1948
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1949 vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1950 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1951 values_propagated = false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1952 num_vr_values = num_ssa_names * 2;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1953 vr_value = XCNEWVEC (value_range_equiv *, num_vr_values);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1954 vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1955 bitmap_obstack_initialize (&vrp_equiv_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1956 to_remove_edges = vNULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1957 to_update_switch_stmts = vNULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1958 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1959
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1960 /* Free VRP lattice. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1961
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1962 vr_values::~vr_values ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1963 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1964 /* Free allocated memory. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1965 free (vr_value);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1966 free (vr_phi_edge_counts);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1967 bitmap_obstack_release (&vrp_equiv_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1968 vrp_value_range_pool.release ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1969
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1970 /* So that we can distinguish between VRP data being available
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1971 and not available. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1972 vr_value = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1973 vr_phi_edge_counts = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1974
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1975 /* If there are entries left in TO_REMOVE_EDGES or TO_UPDATE_SWITCH_STMTS
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1976 then an EVRP client did not clean up properly. Catch it now rather
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1977 than seeing something more obscure later. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1978 gcc_assert (to_remove_edges.is_empty ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1979 && to_update_switch_stmts.is_empty ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1980 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1981
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1982
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1983 /* A hack. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1984 static class vr_values *x_vr_values;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1985
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1986 /* Return the singleton value-range for NAME or NAME. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1987
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1988 static inline tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1989 vrp_valueize (tree name)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1990 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1991 if (TREE_CODE (name) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1992 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
1993 const value_range_equiv *vr = x_vr_values->get_value_range (name);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1994 if (vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1995 && (TREE_CODE (vr->min ()) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1996 || is_gimple_min_invariant (vr->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1997 && vrp_operand_equal_p (vr->min (), vr->max ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1998 return vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1999 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2000 return name;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2001 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2002
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2003 /* Return the singleton value-range for NAME if that is a constant
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2004 but signal to not follow SSA edges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2005
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2006 static inline tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2007 vrp_valueize_1 (tree name)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2008 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2009 if (TREE_CODE (name) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2010 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2011 /* If the definition may be simulated again we cannot follow
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2012 this SSA edge as the SSA propagator does not necessarily
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2013 re-visit the use. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2014 gimple *def_stmt = SSA_NAME_DEF_STMT (name);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2015 if (!gimple_nop_p (def_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2016 && prop_simulate_again_p (def_stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2017 return NULL_TREE;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2018 const value_range_equiv *vr = x_vr_values->get_value_range (name);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2019 tree singleton;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2020 if (vr->singleton_p (&singleton))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2021 return singleton;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2022 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2023 return name;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2024 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2025
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2026 /* Given STMT, an assignment or call, return its LHS if the type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2027 of the LHS is suitable for VRP analysis, else return NULL_TREE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2028
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2029 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2030 get_output_for_vrp (gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2031 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2032 if (!is_gimple_assign (stmt) && !is_gimple_call (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2033 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2034
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2035 /* We only keep track of ranges in integral and pointer types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2036 tree lhs = gimple_get_lhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2037 if (TREE_CODE (lhs) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2038 && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2039 /* It is valid to have NULL MIN/MAX values on a type. See
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2040 build_range_type. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2041 && TYPE_MIN_VALUE (TREE_TYPE (lhs))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2042 && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2043 || POINTER_TYPE_P (TREE_TYPE (lhs))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2044 return lhs;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2045
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2046 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2047 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2048
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2049 /* Visit assignment STMT. If it produces an interesting range, record
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2050 the range in VR and set LHS to OUTPUT_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2051
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2052 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2053 vr_values::vrp_visit_assignment_or_call (gimple *stmt, tree *output_p,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2054 value_range_equiv *vr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2055 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2056 tree lhs = get_output_for_vrp (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2057 *output_p = lhs;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2058
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2059 /* We only keep track of ranges in integral and pointer types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2060 if (lhs)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2061 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2062 enum gimple_code code = gimple_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2063
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2064 /* Try folding the statement to a constant first. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2065 x_vr_values = this;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2066 tree tem = gimple_fold_stmt_to_constant_1 (stmt, vrp_valueize,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2067 vrp_valueize_1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2068 x_vr_values = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2069 if (tem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2070 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2071 if (TREE_CODE (tem) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2072 && (SSA_NAME_IS_DEFAULT_DEF (tem)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2073 || ! prop_simulate_again_p (SSA_NAME_DEF_STMT (tem))))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2074 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2075 extract_range_from_ssa_name (vr, tem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2076 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2077 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2078 else if (is_gimple_min_invariant (tem))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2079 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2080 vr->set (tem);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2081 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2082 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2083 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2084 /* Then dispatch to value-range extracting functions. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2085 if (code == GIMPLE_CALL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2086 extract_range_basic (vr, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2087 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2088 extract_range_from_assignment (vr, as_a <gassign *> (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2089 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2090 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2091
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2092 /* Helper that gets the value range of the SSA_NAME with version I
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2093 or a symbolic range containing the SSA_NAME only if the value range
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2094 is varying or undefined. Uses TEM as storage for the alternate range. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2095
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2096 const value_range_equiv *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2097 vr_values::get_vr_for_comparison (int i, value_range_equiv *tem)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2098 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2099 /* Shallow-copy equiv bitmap. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2100 const value_range_equiv *vr = get_value_range (ssa_name (i));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2101
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2102 /* If name N_i does not have a valid range, use N_i as its own
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2103 range. This allows us to compare against names that may
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2104 have N_i in their ranges. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2105 if (vr->varying_p () || vr->undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2106 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2107 tem->set (ssa_name (i));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2108 return tem;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2109 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2110
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2111 return vr;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2112 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2113
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2114 /* Compare all the value ranges for names equivalent to VAR with VAL
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2115 using comparison code COMP. Return the same value returned by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2116 compare_range_with_value, including the setting of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2117 *STRICT_OVERFLOW_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2118
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2119 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2120 vr_values::compare_name_with_value (enum tree_code comp, tree var, tree val,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2121 bool *strict_overflow_p, bool use_equiv_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2122 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2123 /* Get the set of equivalences for VAR. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2124 bitmap e = get_value_range (var)->equiv ();
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2125
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2126 /* Start at -1. Set it to 0 if we do a comparison without relying
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2127 on overflow, or 1 if all comparisons rely on overflow. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2128 int used_strict_overflow = -1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2129
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2130 /* Compare vars' value range with val. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2131 value_range_equiv tem_vr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2132 const value_range_equiv *equiv_vr
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2133 = get_vr_for_comparison (SSA_NAME_VERSION (var), &tem_vr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2134 bool sop = false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2135 tree retval = compare_range_with_value (comp, equiv_vr, val, &sop);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2136 if (retval)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2137 used_strict_overflow = sop ? 1 : 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2138
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2139 /* If the equiv set is empty we have done all work we need to do. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2140 if (e == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2141 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2142 if (retval && used_strict_overflow > 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2143 *strict_overflow_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2144 return retval;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2145 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2146
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2147 unsigned i;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2148 bitmap_iterator bi;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2149 EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2150 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2151 tree name = ssa_name (i);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2152 if (!name)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2153 continue;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2154
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2155 if (!use_equiv_p
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2156 && !SSA_NAME_IS_DEFAULT_DEF (name)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2157 && prop_simulate_again_p (SSA_NAME_DEF_STMT (name)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2158 continue;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2159
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2160 equiv_vr = get_vr_for_comparison (i, &tem_vr);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2161 sop = false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2162 tree t = compare_range_with_value (comp, equiv_vr, val, &sop);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2163 if (t)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2164 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2165 /* If we get different answers from different members
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2166 of the equivalence set this check must be in a dead
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2167 code region. Folding it to a trap representation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2168 would be correct here. For now just return don't-know. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2169 if (retval != NULL
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2170 && t != retval)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2171 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2172 retval = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2173 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2174 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2175 retval = t;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2176
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2177 if (!sop)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2178 used_strict_overflow = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2179 else if (used_strict_overflow < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2180 used_strict_overflow = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2181 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2182 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2183
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2184 if (retval && used_strict_overflow > 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2185 *strict_overflow_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2186
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2187 return retval;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2188 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2189
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2190
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2191 /* Given a comparison code COMP and names N1 and N2, compare all the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2192 ranges equivalent to N1 against all the ranges equivalent to N2
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2193 to determine the value of N1 COMP N2. Return the same value
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2194 returned by compare_ranges. Set *STRICT_OVERFLOW_P to indicate
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2195 whether we relied on undefined signed overflow in the comparison. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2196
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2197
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2198 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2199 vr_values::compare_names (enum tree_code comp, tree n1, tree n2,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2200 bool *strict_overflow_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2201 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2202 /* Compare the ranges of every name equivalent to N1 against the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2203 ranges of every name equivalent to N2. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2204 bitmap e1 = get_value_range (n1)->equiv ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2205 bitmap e2 = get_value_range (n2)->equiv ();
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2206
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2207 /* Use the fake bitmaps if e1 or e2 are not available. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2208 static bitmap s_e1 = NULL, s_e2 = NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2209 static bitmap_obstack *s_obstack = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2210 if (s_obstack == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2211 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2212 s_obstack = XNEW (bitmap_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2213 bitmap_obstack_initialize (s_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2214 s_e1 = BITMAP_ALLOC (s_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2215 s_e2 = BITMAP_ALLOC (s_obstack);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2216 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2217 if (e1 == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2218 e1 = s_e1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2219 if (e2 == NULL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2220 e2 = s_e2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2221
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2222 /* Add N1 and N2 to their own set of equivalences to avoid
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2223 duplicating the body of the loop just to check N1 and N2
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2224 ranges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2225 bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2226 bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2227
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2228 /* If the equivalence sets have a common intersection, then the two
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2229 names can be compared without checking their ranges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2230 if (bitmap_intersect_p (e1, e2))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2231 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2232 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2233 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2234
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2235 return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2236 ? boolean_true_node
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2237 : boolean_false_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2238 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2239
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2240 /* Start at -1. Set it to 0 if we do a comparison without relying
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2241 on overflow, or 1 if all comparisons rely on overflow. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2242 int used_strict_overflow = -1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2243
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2244 /* Otherwise, compare all the equivalent ranges. First, add N1 and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2245 N2 to their own set of equivalences to avoid duplicating the body
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2246 of the loop just to check N1 and N2 ranges. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2247 bitmap_iterator bi1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2248 unsigned i1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2249 EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2250 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2251 if (!ssa_name (i1))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2252 continue;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2253
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2254 value_range_equiv tem_vr1;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2255 const value_range_equiv *vr1 = get_vr_for_comparison (i1, &tem_vr1);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2256
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2257 tree t = NULL_TREE, retval = NULL_TREE;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2258 bitmap_iterator bi2;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2259 unsigned i2;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2260 EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2261 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2262 if (!ssa_name (i2))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2263 continue;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2264
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2265 bool sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2266
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2267 value_range_equiv tem_vr2;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2268 const value_range_equiv *vr2 = get_vr_for_comparison (i2, &tem_vr2);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2269
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2270 t = compare_ranges (comp, vr1, vr2, &sop);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2271 if (t)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2272 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2273 /* If we get different answers from different members
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2274 of the equivalence set this check must be in a dead
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2275 code region. Folding it to a trap representation
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2276 would be correct here. For now just return don't-know. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2277 if (retval != NULL && t != retval)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2278 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2279 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2280 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2281 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2282 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2283 retval = t;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2284
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2285 if (!sop)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2286 used_strict_overflow = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2287 else if (used_strict_overflow < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2288 used_strict_overflow = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2289 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2290 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2291
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2292 if (retval)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2293 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2294 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2295 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2296 if (used_strict_overflow > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2297 *strict_overflow_p = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2298 return retval;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2299 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2300 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2301
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2302 /* None of the equivalent ranges are useful in computing this
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2303 comparison. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2304 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2305 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2306 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2307 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2308
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2309 /* Helper function for vrp_evaluate_conditional_warnv & other
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2310 optimizers. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2311
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2312 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2313 vr_values::vrp_evaluate_conditional_warnv_with_ops_using_ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2314 (enum tree_code code, tree op0, tree op1, bool * strict_overflow_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2315 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2316 const value_range_equiv *vr0, *vr1;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2317 vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2318 vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2319
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2320 tree res = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2321 if (vr0 && vr1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2322 res = compare_ranges (code, vr0, vr1, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2323 if (!res && vr0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2324 res = compare_range_with_value (code, vr0, op1, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2325 if (!res && vr1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2326 res = (compare_range_with_value
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2327 (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2328 return res;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2329 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2330
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2331 /* Helper function for vrp_evaluate_conditional_warnv. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2332
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2333 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2334 vr_values::vrp_evaluate_conditional_warnv_with_ops (enum tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2335 tree op0, tree op1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2336 bool use_equiv_p,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2337 bool *strict_overflow_p,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2338 bool *only_ranges)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2339 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2340 tree ret;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2341 if (only_ranges)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2342 *only_ranges = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2343
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2344 /* We only deal with integral and pointer types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2345 if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2346 && !POINTER_TYPE_P (TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2347 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2348
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2349 /* If OP0 CODE OP1 is an overflow comparison, if it can be expressed
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2350 as a simple equality test, then prefer that over its current form
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2351 for evaluation.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2352
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2353 An overflow test which collapses to an equality test can always be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2354 expressed as a comparison of one argument against zero. Overflow
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2355 occurs when the chosen argument is zero and does not occur if the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2356 chosen argument is not zero. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2357 tree x;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2358 if (overflow_comparison_p (code, op0, op1, use_equiv_p, &x))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2359 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2360 wide_int max = wi::max_value (TYPE_PRECISION (TREE_TYPE (op0)), UNSIGNED);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2361 /* B = A - 1; if (A < B) -> B = A - 1; if (A == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2362 B = A - 1; if (A > B) -> B = A - 1; if (A != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2363 B = A + 1; if (B < A) -> B = A + 1; if (B == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2364 B = A + 1; if (B > A) -> B = A + 1; if (B != 0) */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2365 if (integer_zerop (x))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2366 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2367 op1 = x;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2368 code = (code == LT_EXPR || code == LE_EXPR) ? EQ_EXPR : NE_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2369 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2370 /* B = A + 1; if (A > B) -> B = A + 1; if (B == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2371 B = A + 1; if (A < B) -> B = A + 1; if (B != 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2372 B = A - 1; if (B > A) -> B = A - 1; if (A == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2373 B = A - 1; if (B < A) -> B = A - 1; if (A != 0) */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2374 else if (wi::to_wide (x) == max - 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2375 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2376 op0 = op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2377 op1 = wide_int_to_tree (TREE_TYPE (op0), 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2378 code = (code == GT_EXPR || code == GE_EXPR) ? EQ_EXPR : NE_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2379 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2380 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2381 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2382 value_range vro, vri;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2383 if (code == GT_EXPR || code == GE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2384 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2385 vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2386 vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2387 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2388 else if (code == LT_EXPR || code == LE_EXPR)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2389 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2390 vro.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2391 vri.set (TYPE_MIN_VALUE (TREE_TYPE (op0)), x, VR_ANTI_RANGE);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2392 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2393 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2394 gcc_unreachable ();
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2395 const value_range_equiv *vr0 = get_value_range (op0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2396 /* If vro, the range for OP0 to pass the overflow test, has
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2397 no intersection with *vr0, OP0's known range, then the
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2398 overflow test can't pass, so return the node for false.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2399 If it is the inverted range, vri, that has no
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2400 intersection, then the overflow test must pass, so return
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2401 the node for true. In other cases, we could proceed with
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2402 a simplified condition comparing OP0 and X, with LE_EXPR
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2403 for previously LE_ or LT_EXPR and GT_EXPR otherwise, but
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2404 the comments next to the enclosing if suggest it's not
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2405 generally profitable to do so. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2406 vro.intersect (vr0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2407 if (vro.undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2408 return boolean_false_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2409 vri.intersect (vr0);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2410 if (vri.undefined_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2411 return boolean_true_node;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2412 }
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2413 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2414
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2415 if ((ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2416 (code, op0, op1, strict_overflow_p)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2417 return ret;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2418 if (only_ranges)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2419 *only_ranges = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2420 /* Do not use compare_names during propagation, it's quadratic. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2421 if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2422 && use_equiv_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2423 return compare_names (code, op0, op1, strict_overflow_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2424 else if (TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2425 return compare_name_with_value (code, op0, op1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2426 strict_overflow_p, use_equiv_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2427 else if (TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2428 return compare_name_with_value (swap_tree_comparison (code), op1, op0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2429 strict_overflow_p, use_equiv_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2430 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2431 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2432
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2433 /* Given (CODE OP0 OP1) within STMT, try to simplify it based on value range
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2434 information. Return NULL if the conditional cannot be evaluated.
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2435 The ranges of all the names equivalent with the operands in COND
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2436 will be used when trying to compute the value. If the result is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2437 based on undefined signed overflow, issue a warning if
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2438 appropriate. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2439
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2440 tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2441 vr_values::vrp_evaluate_conditional (tree_code code, tree op0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2442 tree op1, gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2443 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2444 bool sop;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2445 tree ret;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2446 bool only_ranges;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2447
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2448 /* Some passes and foldings leak constants with overflow flag set
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2449 into the IL. Avoid doing wrong things with these and bail out. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2450 if ((TREE_CODE (op0) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2451 && TREE_OVERFLOW (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2452 || (TREE_CODE (op1) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2453 && TREE_OVERFLOW (op1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2454 return NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2455
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2456 sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2457 ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2458 &only_ranges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2459
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2460 if (ret && sop)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2461 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2462 enum warn_strict_overflow_code wc;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2463 const char* warnmsg;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2464
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2465 if (is_gimple_min_invariant (ret))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2466 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2467 wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2468 warnmsg = G_("assuming signed overflow does not occur when "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2469 "simplifying conditional to constant");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2470 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2471 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2472 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2473 wc = WARN_STRICT_OVERFLOW_COMPARISON;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2474 warnmsg = G_("assuming signed overflow does not occur when "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2475 "simplifying conditional");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2476 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2477
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2478 if (issue_strict_overflow_warning (wc))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2479 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2480 location_t location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2481
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2482 if (!gimple_has_location (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2483 location = input_location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2484 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2485 location = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2486 warning_at (location, OPT_Wstrict_overflow, "%s", warnmsg);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2487 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2488 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2489
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2490 if (warn_type_limits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2491 && ret && only_ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2492 && TREE_CODE_CLASS (code) == tcc_comparison
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2493 && TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2494 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2495 /* If the comparison is being folded and the operand on the LHS
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2496 is being compared against a constant value that is outside of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2497 the natural range of OP0's type, then the predicate will
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2498 always fold regardless of the value of OP0. If -Wtype-limits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2499 was specified, emit a warning. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2500 tree type = TREE_TYPE (op0);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2501 const value_range_equiv *vr0 = get_value_range (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2502
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2503 if (vr0->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2504 && INTEGRAL_TYPE_P (type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2505 && vrp_val_is_min (vr0->min ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2506 && vrp_val_is_max (vr0->max ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2507 && is_gimple_min_invariant (op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2508 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2509 location_t location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2510
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2511 if (!gimple_has_location (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2512 location = input_location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2513 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2514 location = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2515
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2516 warning_at (location, OPT_Wtype_limits,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2517 integer_zerop (ret)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2518 ? G_("comparison always false "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2519 "due to limited range of data type")
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2520 : G_("comparison always true "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2521 "due to limited range of data type"));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2522 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2523 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2524
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2525 return ret;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2526 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2527
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2528
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2529 /* Visit conditional statement STMT. If we can determine which edge
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2530 will be taken out of STMT's basic block, record it in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2531 *TAKEN_EDGE_P. Otherwise, set *TAKEN_EDGE_P to NULL. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2532
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2533 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2534 vr_values::vrp_visit_cond_stmt (gcond *stmt, edge *taken_edge_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2535 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2536 tree val;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2537
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2538 *taken_edge_p = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2539
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2540 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2541 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2542 tree use;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2543 ssa_op_iter i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2544
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2545 fprintf (dump_file, "\nVisiting conditional with predicate: ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2546 print_gimple_stmt (dump_file, stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2547 fprintf (dump_file, "\nWith known ranges\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2548
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2549 FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2550 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2551 fprintf (dump_file, "\t");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2552 print_generic_expr (dump_file, use);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2553 fprintf (dump_file, ": ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2554 dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2555 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2556
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2557 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2558 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2559
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2560 /* Compute the value of the predicate COND by checking the known
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2561 ranges of each of its operands.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2562
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2563 Note that we cannot evaluate all the equivalent ranges here
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2564 because those ranges may not yet be final and with the current
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2565 propagation strategy, we cannot determine when the value ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2566 of the names in the equivalence set have changed.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2567
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2568 For instance, given the following code fragment
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2569
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2570 i_5 = PHI <8, i_13>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2571 ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2572 i_14 = ASSERT_EXPR <i_5, i_5 != 0>
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2573 if (i_14 == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2574 ...
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2575
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2576 Assume that on the first visit to i_14, i_5 has the temporary
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2577 range [8, 8] because the second argument to the PHI function is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2578 not yet executable. We derive the range ~[0, 0] for i_14 and the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2579 equivalence set { i_5 }. So, when we visit 'if (i_14 == 1)' for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2580 the first time, since i_14 is equivalent to the range [8, 8], we
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2581 determine that the predicate is always false.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2582
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2583 On the next round of propagation, i_13 is determined to be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2584 VARYING, which causes i_5 to drop down to VARYING. So, another
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2585 visit to i_14 is scheduled. In this second visit, we compute the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2586 exact same range and equivalence set for i_14, namely ~[0, 0] and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2587 { i_5 }. But we did not have the previous range for i_5
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2588 registered, so vrp_visit_assignment thinks that the range for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2589 i_14 has not changed. Therefore, the predicate 'if (i_14 == 1)'
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2590 is not visited again, which stops propagation from visiting
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2591 statements in the THEN clause of that if().
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2592
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2593 To properly fix this we would need to keep the previous range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2594 value for the names in the equivalence set. This way we would've
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2595 discovered that from one visit to the other i_5 changed from
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2596 range [8, 8] to VR_VARYING.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2597
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2598 However, fixing this apparent limitation may not be worth the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2599 additional checking. Testing on several code bases (GCC, DLV,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2600 MICO, TRAMP3D and SPEC2000) showed that doing this results in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2601 4 more predicates folded in SPEC. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2602
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2603 bool sop;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2604 val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2605 gimple_cond_lhs (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2606 gimple_cond_rhs (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2607 false, &sop, NULL);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2608 if (val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2609 *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2610
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2611 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2612 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2613 fprintf (dump_file, "\nPredicate evaluates to: ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2614 if (val == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2615 fprintf (dump_file, "DON'T KNOW\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2616 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2617 print_generic_stmt (dump_file, val);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2618 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2619 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2620
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2621 /* Searches the case label vector VEC for the ranges of CASE_LABELs that are
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2622 used in range VR. The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2623 MAX_IDX2. If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2624 Returns true if the default label is not needed. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2625
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2626 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2627 find_case_label_ranges (gswitch *stmt, const value_range_equiv *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2628 size_t *min_idx1, size_t *max_idx1,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2629 size_t *min_idx2, size_t *max_idx2)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2630 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2631 size_t i, j, k, l;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2632 unsigned int n = gimple_switch_num_labels (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2633 bool take_default;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2634 tree case_low, case_high;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2635 tree min = vr->min (), max = vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2636
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2637 gcc_checking_assert (!vr->varying_p () && !vr->undefined_p ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2638
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2639 take_default = !find_case_label_range (stmt, min, max, &i, &j);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2640
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2641 /* Set second range to empty. */
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2642 *min_idx2 = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2643 *max_idx2 = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2644
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2645 if (vr->kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2646 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2647 *min_idx1 = i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2648 *max_idx1 = j;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2649 return !take_default;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2650 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2651
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2652 /* Set first range to all case labels. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2653 *min_idx1 = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2654 *max_idx1 = n - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2655
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2656 if (i > j)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2657 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2658
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2659 /* Make sure all the values of case labels [i , j] are contained in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2660 range [MIN, MAX]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2661 case_low = CASE_LOW (gimple_switch_label (stmt, i));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2662 case_high = CASE_HIGH (gimple_switch_label (stmt, j));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2663 if (tree_int_cst_compare (case_low, min) < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2664 i += 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2665 if (case_high != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2666 && tree_int_cst_compare (max, case_high) < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2667 j -= 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2668
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2669 if (i > j)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2670 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2671
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2672 /* If the range spans case labels [i, j], the corresponding anti-range spans
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2673 the labels [1, i - 1] and [j + 1, n - 1]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2674 k = j + 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2675 l = n - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2676 if (k > l)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2677 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2678 k = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2679 l = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2680 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2681
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2682 j = i - 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2683 i = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2684 if (i > j)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2685 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2686 i = k;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2687 j = l;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2688 k = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2689 l = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2690 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2691
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2692 *min_idx1 = i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2693 *max_idx1 = j;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2694 *min_idx2 = k;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2695 *max_idx2 = l;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2696 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2697 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2698
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2699 /* Visit switch statement STMT. If we can determine which edge
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2700 will be taken out of STMT's basic block, record it in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2701 *TAKEN_EDGE_P. Otherwise, *TAKEN_EDGE_P set to NULL. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2702
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2703 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2704 vr_values::vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2705 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2706 tree op, val;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2707 const value_range_equiv *vr;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2708 size_t i = 0, j = 0, k, l;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2709 bool take_default;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2710
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2711 *taken_edge_p = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2712 op = gimple_switch_index (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2713 if (TREE_CODE (op) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2714 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2715
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2716 vr = get_value_range (op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2717 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2718 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2719 fprintf (dump_file, "\nVisiting switch expression with operand ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2720 print_generic_expr (dump_file, op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2721 fprintf (dump_file, " with known range ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2722 dump_value_range (dump_file, vr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2723 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2724 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2725
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2726 if (vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2727 || vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2728 || vr->symbolic_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2729 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2730
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2731 /* Find the single edge that is taken from the switch expression. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2732 take_default = !find_case_label_ranges (stmt, vr, &i, &j, &k, &l);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2733
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2734 /* Check if the range spans no CASE_LABEL. If so, we only reach the default
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2735 label */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2736 if (j < i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2737 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2738 gcc_assert (take_default);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2739 val = gimple_switch_default_label (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2740 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2741 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2742 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2743 /* Check if labels with index i to j and maybe the default label
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2744 are all reaching the same label. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2745
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2746 val = gimple_switch_label (stmt, i);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2747 if (take_default
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2748 && CASE_LABEL (gimple_switch_default_label (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2749 != CASE_LABEL (val))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2750 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2751 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2752 fprintf (dump_file, " not a single destination for this "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2753 "range\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2754 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2755 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2756 for (++i; i <= j; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2757 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2758 if (CASE_LABEL (gimple_switch_label (stmt, i)) != CASE_LABEL (val))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2759 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2760 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2761 fprintf (dump_file, " not a single destination for this "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2762 "range\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2763 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2764 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2765 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2766 for (; k <= l; ++k)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2767 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2768 if (CASE_LABEL (gimple_switch_label (stmt, k)) != CASE_LABEL (val))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2769 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2770 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2771 fprintf (dump_file, " not a single destination for this "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2772 "range\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2773 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2774 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2775 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2776 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2777
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2778 *taken_edge_p = find_edge (gimple_bb (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2779 label_to_block (cfun, CASE_LABEL (val)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2780
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2781 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2782 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2783 fprintf (dump_file, " will take edge to ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2784 print_generic_stmt (dump_file, CASE_LABEL (val));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2785 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2786 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2787
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2788
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2789 /* Evaluate statement STMT. If the statement produces a useful range,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2790 set VR and corepsponding OUTPUT_P.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2791
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2792 If STMT is a conditional branch and we can determine its truth
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2793 value, the taken edge is recorded in *TAKEN_EDGE_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2794
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2795 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2796 vr_values::extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2797 tree *output_p, value_range_equiv *vr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2798 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2799
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2800 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2801 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2802 fprintf (dump_file, "\nVisiting statement:\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2803 print_gimple_stmt (dump_file, stmt, 0, dump_flags);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2804 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2805
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2806 if (!stmt_interesting_for_vrp (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2807 gcc_assert (stmt_ends_bb_p (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2808 else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2809 vrp_visit_assignment_or_call (stmt, output_p, vr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2810 else if (gimple_code (stmt) == GIMPLE_COND)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2811 vrp_visit_cond_stmt (as_a <gcond *> (stmt), taken_edge_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2812 else if (gimple_code (stmt) == GIMPLE_SWITCH)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2813 vrp_visit_switch_stmt (as_a <gswitch *> (stmt), taken_edge_p);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2814 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2815
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2816 /* Visit all arguments for PHI node PHI that flow through executable
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2817 edges. If a valid value range can be derived from all the incoming
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2818 value ranges, set a new range in VR_RESULT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2819
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2820 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2821 vr_values::extract_range_from_phi_node (gphi *phi,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2822 value_range_equiv *vr_result)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2823 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2824 tree lhs = PHI_RESULT (phi);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2825 const value_range_equiv *lhs_vr = get_value_range (lhs);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2826 bool first = true;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2827 int old_edges;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2828 class loop *l;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2829
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2830 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2831 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2832 fprintf (dump_file, "\nVisiting PHI node: ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2833 print_gimple_stmt (dump_file, phi, 0, dump_flags);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2834 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2835
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2836 bool may_simulate_backedge_again = false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2837 int edges = 0;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2838 for (size_t i = 0; i < gimple_phi_num_args (phi); i++)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2839 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2840 edge e = gimple_phi_arg_edge (phi, i);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2841
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2842 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2843 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2844 fprintf (dump_file,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2845 " Argument #%d (%d -> %d %sexecutable)\n",
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2846 (int) i, e->src->index, e->dest->index,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2847 (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2848 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2849
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2850 if (e->flags & EDGE_EXECUTABLE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2851 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2852 value_range_equiv vr_arg_tem;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2853 const value_range_equiv *vr_arg = &vr_arg_tem;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2854
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2855 ++edges;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2856
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2857 tree arg = PHI_ARG_DEF (phi, i);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2858 if (TREE_CODE (arg) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2859 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2860 /* See if we are eventually going to change one of the args. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2861 gimple *def_stmt = SSA_NAME_DEF_STMT (arg);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2862 if (! gimple_nop_p (def_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2863 && prop_simulate_again_p (def_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2864 && e->flags & EDGE_DFS_BACK)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2865 may_simulate_backedge_again = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2866
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2867 const value_range_equiv *vr_arg_ = get_value_range (arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2868 /* Do not allow equivalences or symbolic ranges to leak in from
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2869 backedges. That creates invalid equivalencies.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2870 See PR53465 and PR54767. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2871 if (e->flags & EDGE_DFS_BACK)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2872 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2873 if (!vr_arg_->varying_p () && !vr_arg_->undefined_p ())
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2874 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2875 vr_arg_tem.set (vr_arg_->min (), vr_arg_->max (), NULL,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2876 vr_arg_->kind ());
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2877 if (vr_arg_tem.symbolic_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2878 vr_arg_tem.set_varying (TREE_TYPE (arg));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2879 }
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2880 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2881 vr_arg = vr_arg_;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2882 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2883 /* If the non-backedge arguments range is VR_VARYING then
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2884 we can still try recording a simple equivalence. */
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2885 else if (vr_arg_->varying_p ())
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2886 vr_arg_tem.set (arg);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2887 else
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2888 vr_arg = vr_arg_;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2889 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2890 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2891 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2892 if (TREE_OVERFLOW_P (arg))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2893 arg = drop_tree_overflow (arg);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2894
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2895 vr_arg_tem.set (arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2896 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2897
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2898 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2899 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2900 fprintf (dump_file, "\t");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2901 print_generic_expr (dump_file, arg, dump_flags);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2902 fprintf (dump_file, ": ");
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2903 dump_value_range (dump_file, vr_arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2904 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2905 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2906
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2907 if (first)
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2908 vr_result->deep_copy (vr_arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2909 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2910 vr_result->union_ (vr_arg);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2911 first = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2912
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2913 if (vr_result->varying_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2914 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2915 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2916 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2917
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2918 if (vr_result->varying_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2919 goto varying;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2920 else if (vr_result->undefined_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2921 goto update_range;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2922
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2923 old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2924 vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2925
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2926 /* To prevent infinite iterations in the algorithm, derive ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2927 when the new value is slightly bigger or smaller than the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2928 previous one. We don't do this if we have seen a new executable
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2929 edge; this helps us avoid an infinity for conditionals
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2930 which are not in a loop. If the old value-range was VR_UNDEFINED
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2931 use the updated range and iterate one more time. If we will not
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2932 simulate this PHI again via the backedge allow us to iterate. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2933 if (edges > 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2934 && gimple_phi_num_args (phi) > 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2935 && edges == old_edges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2936 && !lhs_vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2937 && may_simulate_backedge_again)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2938 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2939 /* Compare old and new ranges, fall back to varying if the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2940 values are not comparable. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2941 int cmp_min = compare_values (lhs_vr->min (), vr_result->min ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2942 if (cmp_min == -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2943 goto varying;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2944 int cmp_max = compare_values (lhs_vr->max (), vr_result->max ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2945 if (cmp_max == -2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2946 goto varying;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2947
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2948 /* For non VR_RANGE or for pointers fall back to varying if
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2949 the range changed. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2950 if ((lhs_vr->kind () != VR_RANGE || vr_result->kind () != VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2951 || POINTER_TYPE_P (TREE_TYPE (lhs)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2952 && (cmp_min != 0 || cmp_max != 0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2953 goto varying;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2954
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2955 /* If the new minimum is larger than the previous one
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2956 retain the old value. If the new minimum value is smaller
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2957 than the previous one and not -INF go all the way to -INF + 1.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2958 In the first case, to avoid infinite bouncing between different
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2959 minimums, and in the other case to avoid iterating millions of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2960 times to reach -INF. Going to -INF + 1 also lets the following
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2961 iteration compute whether there will be any overflow, at the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2962 expense of one additional iteration. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2963 tree new_min = vr_result->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2964 tree new_max = vr_result->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2965 if (cmp_min < 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2966 new_min = lhs_vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2967 else if (cmp_min > 0
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2968 && (TREE_CODE (vr_result->min ()) != INTEGER_CST
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2969 || tree_int_cst_lt (vrp_val_min (vr_result->type ()),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2970 vr_result->min ())))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2971 new_min = int_const_binop (PLUS_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2972 vrp_val_min (vr_result->type ()),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2973 build_int_cst (vr_result->type (), 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2974
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2975 /* Similarly for the maximum value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2976 if (cmp_max > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2977 new_max = lhs_vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2978 else if (cmp_max < 0
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2979 && (TREE_CODE (vr_result->max ()) != INTEGER_CST
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2980 || tree_int_cst_lt (vr_result->max (),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2981 vrp_val_max (vr_result->type ()))))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2982 new_max = int_const_binop (MINUS_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2983 vrp_val_max (vr_result->type ()),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2984 build_int_cst (vr_result->type (), 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2985
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2986 vr_result->update (new_min, new_max, vr_result->kind ());
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2987
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2988 /* If we dropped either bound to +-INF then if this is a loop
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2989 PHI node SCEV may known more about its value-range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2990 if (cmp_min > 0 || cmp_min < 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2991 || cmp_max < 0 || cmp_max > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2992 goto scev_check;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2993
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2994 goto infinite_check;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2995 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2996
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2997 goto update_range;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2998
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2999 varying:
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3000 vr_result->set_varying (TREE_TYPE (lhs));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3001
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3002 scev_check:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3003 /* If this is a loop PHI node SCEV may known more about its value-range.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3004 scev_check can be reached from two paths, one is a fall through from above
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3005 "varying" label, the other is direct goto from code block which tries to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3006 avoid infinite simulation. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3007 if (scev_initialized_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3008 && (l = loop_containing_stmt (phi))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3009 && l->header == gimple_bb (phi))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3010 adjust_range_with_scev (vr_result, l, phi, lhs);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3011
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3012 infinite_check:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3013 /* If we will end up with a (-INF, +INF) range, set it to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3014 VARYING. Same if the previous max value was invalid for
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3015 the type and we end up with vr_result.min > vr_result.max. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3016 if ((!vr_result->varying_p () && !vr_result->undefined_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3017 && !((vrp_val_is_max (vr_result->max ()) && vrp_val_is_min (vr_result->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3018 || compare_values (vr_result->min (), vr_result->max ()) > 0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3019 ;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3020 else
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3021 vr_result->set_varying (TREE_TYPE (lhs));
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3022
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3023 /* If the new range is different than the previous value, keep
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3024 iterating. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3025 update_range:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3026 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3027 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3028
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3029 /* Simplify boolean operations if the source is known
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3030 to be already a boolean. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3031 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3032 vr_values::simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3033 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3034 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3035 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3036 tree lhs, op0, op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3037 bool need_conversion;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3038
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3039 /* We handle only !=/== case here. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3040 gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3041
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3042 op0 = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3043 if (!op_with_boolean_value_range_p (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3044 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3045
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3046 op1 = gimple_assign_rhs2 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3047 if (!op_with_boolean_value_range_p (op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3048 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3049
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3050 /* Reduce number of cases to handle to NE_EXPR. As there is no
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3051 BIT_XNOR_EXPR we cannot replace A == B with a single statement. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3052 if (rhs_code == EQ_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3053 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3054 if (TREE_CODE (op1) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3055 op1 = int_const_binop (BIT_XOR_EXPR, op1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3056 build_int_cst (TREE_TYPE (op1), 1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3057 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3058 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3059 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3060
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3061 lhs = gimple_assign_lhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3062 need_conversion
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3063 = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3064
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3065 /* Make sure to not sign-extend a 1-bit 1 when converting the result. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3066 if (need_conversion
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3067 && !TYPE_UNSIGNED (TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3068 && TYPE_PRECISION (TREE_TYPE (op0)) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3069 && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3070 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3071
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3072 /* For A != 0 we can substitute A itself. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3073 if (integer_zerop (op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3074 gimple_assign_set_rhs_with_ops (gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3075 need_conversion
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3076 ? NOP_EXPR : TREE_CODE (op0), op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3077 /* For A != B we substitute A ^ B. Either with conversion. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3078 else if (need_conversion)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3079 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3080 tree tem = make_ssa_name (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3081 gassign *newop
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3082 = gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3083 gsi_insert_before (gsi, newop, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3084 if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3085 && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3086 set_range_info (tem, VR_RANGE,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3087 wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3088 wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3089 gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3090 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3091 /* Or without. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3092 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3093 gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3094 update_stmt (gsi_stmt (*gsi));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3095 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3096
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3097 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3098 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3099
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3100 /* Simplify a division or modulo operator to a right shift or bitwise and
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3101 if the first operand is unsigned or is greater than zero and the second
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3102 operand is an exact power of two. For TRUNC_MOD_EXPR op0 % op1 with
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3103 constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3104 optimize it into just op0 if op0's range is known to be a subset of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3105 [-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3106 modulo. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3107
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3108 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3109 vr_values::simplify_div_or_mod_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3110 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3111 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3112 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3113 tree val = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3114 tree op0 = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3115 tree op1 = gimple_assign_rhs2 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3116 tree op0min = NULL_TREE, op0max = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3117 tree op1min = op1;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3118 const value_range_equiv *vr = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3119
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3120 if (TREE_CODE (op0) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3121 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3122 op0min = op0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3123 op0max = op0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3124 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3125 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3126 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3127 vr = get_value_range (op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3128 if (range_int_cst_p (vr))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3129 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3130 op0min = vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3131 op0max = vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3132 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3133 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3134
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3135 if (rhs_code == TRUNC_MOD_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3136 && TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3137 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3138 const value_range_equiv *vr1 = get_value_range (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3139 if (range_int_cst_p (vr1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3140 op1min = vr1->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3141 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3142 if (rhs_code == TRUNC_MOD_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3143 && TREE_CODE (op1min) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3144 && tree_int_cst_sgn (op1min) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3145 && op0max
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3146 && tree_int_cst_lt (op0max, op1min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3147 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3148 if (TYPE_UNSIGNED (TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3149 || tree_int_cst_sgn (op0min) >= 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3150 || tree_int_cst_lt (fold_unary (NEGATE_EXPR, TREE_TYPE (op1min), op1min),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3151 op0min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3152 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3153 /* If op0 already has the range op0 % op1 has,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3154 then TRUNC_MOD_EXPR won't change anything. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3155 gimple_assign_set_rhs_from_tree (gsi, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3156 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3157 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3158 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3159
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3160 if (TREE_CODE (op0) != SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3161 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3162
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3163 if (!integer_pow2p (op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3164 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3165 /* X % -Y can be only optimized into X % Y either if
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3166 X is not INT_MIN, or Y is not -1. Fold it now, as after
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3167 remove_range_assertions the range info might be not available
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3168 anymore. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3169 if (rhs_code == TRUNC_MOD_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3170 && fold_stmt (gsi, follow_single_use_edges))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3171 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3172 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3173 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3174
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3175 if (TYPE_UNSIGNED (TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3176 val = integer_one_node;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3177 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3178 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3179 bool sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3180
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3181 val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3182
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3183 if (val
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3184 && sop
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3185 && integer_onep (val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3186 && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3187 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3188 location_t location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3189
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3190 if (!gimple_has_location (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3191 location = input_location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3192 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3193 location = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3194 warning_at (location, OPT_Wstrict_overflow,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3195 "assuming signed overflow does not occur when "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3196 "simplifying %</%> or %<%%%> to %<>>%> or %<&%>");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3197 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3198 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3199
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3200 if (val && integer_onep (val))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3201 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3202 tree t;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3203
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3204 if (rhs_code == TRUNC_DIV_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3205 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3206 t = build_int_cst (integer_type_node, tree_log2 (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3207 gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3208 gimple_assign_set_rhs1 (stmt, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3209 gimple_assign_set_rhs2 (stmt, t);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3210 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3211 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3212 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3213 t = build_int_cst (TREE_TYPE (op1), 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3214 t = int_const_binop (MINUS_EXPR, op1, t);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3215 t = fold_convert (TREE_TYPE (op0), t);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3216
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3217 gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3218 gimple_assign_set_rhs1 (stmt, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3219 gimple_assign_set_rhs2 (stmt, t);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3220 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3221
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3222 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3223 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3224 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3225 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3226
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3227 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3228 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3229
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3230 /* Simplify a min or max if the ranges of the two operands are
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3231 disjoint. Return true if we do simplify. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3232
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3233 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3234 vr_values::simplify_min_or_max_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3235 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3236 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3237 tree op0 = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3238 tree op1 = gimple_assign_rhs2 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3239 bool sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3240 tree val;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3241
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3242 val = (vrp_evaluate_conditional_warnv_with_ops_using_ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3243 (LE_EXPR, op0, op1, &sop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3244 if (!val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3245 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3246 sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3247 val = (vrp_evaluate_conditional_warnv_with_ops_using_ranges
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3248 (LT_EXPR, op0, op1, &sop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3249 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3250
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3251 if (val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3252 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3253 if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3254 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3255 location_t location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3256
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3257 if (!gimple_has_location (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3258 location = input_location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3259 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3260 location = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3261 warning_at (location, OPT_Wstrict_overflow,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3262 "assuming signed overflow does not occur when "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3263 "simplifying %<min/max (X,Y)%> to %<X%> or %<Y%>");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3264 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3265
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3266 /* VAL == TRUE -> OP0 < or <= op1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3267 VAL == FALSE -> OP0 > or >= op1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3268 tree res = ((gimple_assign_rhs_code (stmt) == MAX_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3269 == integer_zerop (val)) ? op0 : op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3270 gimple_assign_set_rhs_from_tree (gsi, res);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3271 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3272 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3273
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3274 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3275 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3276
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3277 /* If the operand to an ABS_EXPR is >= 0, then eliminate the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3278 ABS_EXPR. If the operand is <= 0, then simplify the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3279 ABS_EXPR into a NEGATE_EXPR. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3280
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3281 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3282 vr_values::simplify_abs_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3283 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3284 tree op = gimple_assign_rhs1 (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3285 const value_range_equiv *vr = get_value_range (op);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3286
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3287 if (vr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3288 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3289 tree val = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3290 bool sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3291
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3292 val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3293 if (!val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3294 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3295 /* The range is neither <= 0 nor > 0. Now see if it is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3296 either < 0 or >= 0. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3297 sop = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3298 val = compare_range_with_value (LT_EXPR, vr, integer_zero_node,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3299 &sop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3300 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3301
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3302 if (val)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3303 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3304 if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3305 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3306 location_t location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3307
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3308 if (!gimple_has_location (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3309 location = input_location;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3310 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3311 location = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3312 warning_at (location, OPT_Wstrict_overflow,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3313 "assuming signed overflow does not occur when "
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3314 "simplifying %<abs (X)%> to %<X%> or %<-X%>");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3315 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3316
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3317 gimple_assign_set_rhs1 (stmt, op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3318 if (integer_zerop (val))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3319 gimple_assign_set_rhs_code (stmt, SSA_NAME);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3320 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3321 gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3322 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3323 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3324 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3325 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3326 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3327
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3328 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3329 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3330
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3331 /* value_range wrapper for wi_set_zero_nonzero_bits.
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3332
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3333 Return TRUE if VR was a constant range and we were able to compute
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3334 the bit masks. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3335
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3336 static bool
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3337 vr_set_zero_nonzero_bits (const tree expr_type,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3338 const value_range *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3339 wide_int *may_be_nonzero,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3340 wide_int *must_be_nonzero)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3341 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3342 if (range_int_cst_p (vr))
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3343 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3344 wi_set_zero_nonzero_bits (expr_type,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3345 wi::to_wide (vr->min ()),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3346 wi::to_wide (vr->max ()),
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3347 *may_be_nonzero, *must_be_nonzero);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3348 return true;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3349 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3350 *may_be_nonzero = wi::minus_one (TYPE_PRECISION (expr_type));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3351 *must_be_nonzero = wi::zero (TYPE_PRECISION (expr_type));
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3352 return false;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3353 }
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3354
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3355 /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3356 If all the bits that are being cleared by & are already
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3357 known to be zero from VR, or all the bits that are being
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3358 set by | are already known to be one from VR, the bit
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3359 operation is redundant. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3360
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3361 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3362 vr_values::simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3363 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3364 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3365 tree op0 = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3366 tree op1 = gimple_assign_rhs2 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3367 tree op = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3368 value_range vr0, vr1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3369 wide_int may_be_nonzero0, may_be_nonzero1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3370 wide_int must_be_nonzero0, must_be_nonzero1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3371 wide_int mask;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3372
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3373 if (TREE_CODE (op0) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3374 vr0 = *(get_value_range (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3375 else if (is_gimple_min_invariant (op0))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3376 vr0.set (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3377 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3378 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3379
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3380 if (TREE_CODE (op1) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3381 vr1 = *(get_value_range (op1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3382 else if (is_gimple_min_invariant (op1))
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3383 vr1.set (op1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3384 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3385 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3386
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3387 if (!vr_set_zero_nonzero_bits (TREE_TYPE (op0), &vr0, &may_be_nonzero0,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3388 &must_be_nonzero0))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3389 return false;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3390 if (!vr_set_zero_nonzero_bits (TREE_TYPE (op1), &vr1, &may_be_nonzero1,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3391 &must_be_nonzero1))
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3392 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3393
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3394 switch (gimple_assign_rhs_code (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3395 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3396 case BIT_AND_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3397 mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3398 if (mask == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3399 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3400 op = op0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3401 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3402 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3403 mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3404 if (mask == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3405 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3406 op = op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3407 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3408 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3409 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3410 case BIT_IOR_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3411 mask = wi::bit_and_not (may_be_nonzero0, must_be_nonzero1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3412 if (mask == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3413 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3414 op = op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3415 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3416 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3417 mask = wi::bit_and_not (may_be_nonzero1, must_be_nonzero0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3418 if (mask == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3419 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3420 op = op0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3421 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3422 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3423 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3424 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3425 gcc_unreachable ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3426 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3427
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3428 if (op == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3429 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3430
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3431 gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3432 update_stmt (gsi_stmt (*gsi));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3433 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3434 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3435
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3436 /* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3437 a known value range VR.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3438
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3439 If there is one and only one value which will satisfy the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3440 conditional, then return that value. Else return NULL.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3441
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3442 If signed overflow must be undefined for the value to satisfy
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3443 the conditional, then set *STRICT_OVERFLOW_P to true. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3444
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3445 static tree
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3446 test_for_singularity (enum tree_code cond_code, tree op0,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3447 tree op1, const value_range_equiv *vr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3448 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3449 tree min = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3450 tree max = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3451
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3452 /* Extract minimum/maximum values which satisfy the conditional as it was
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3453 written. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3454 if (cond_code == LE_EXPR || cond_code == LT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3455 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3456 min = TYPE_MIN_VALUE (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3457
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3458 max = op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3459 if (cond_code == LT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3460 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3461 tree one = build_int_cst (TREE_TYPE (op0), 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3462 max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3463 /* Signal to compare_values_warnv this expr doesn't overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3464 if (EXPR_P (max))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3465 TREE_NO_WARNING (max) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3466 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3467 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3468 else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3469 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3470 max = TYPE_MAX_VALUE (TREE_TYPE (op0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3471
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3472 min = op1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3473 if (cond_code == GT_EXPR)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3474 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3475 tree one = build_int_cst (TREE_TYPE (op0), 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3476 min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3477 /* Signal to compare_values_warnv this expr doesn't overflow. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3478 if (EXPR_P (min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3479 TREE_NO_WARNING (min) = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3480 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3481 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3482
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3483 /* Now refine the minimum and maximum values using any
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3484 value range information we have for op0. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3485 if (min && max)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3486 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3487 if (compare_values (vr->min (), min) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3488 min = vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3489 if (compare_values (vr->max (), max) == -1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3490 max = vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3491
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3492 /* If the new min/max values have converged to a single value,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3493 then there is only one value which can satisfy the condition,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3494 return that value. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3495 if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3496 return min;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3497 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3498 return NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3499 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3500
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3501 /* Return whether the value range *VR fits in an integer type specified
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3502 by PRECISION and UNSIGNED_P. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3503
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3504 static bool
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3505 range_fits_type_p (const value_range_equiv *vr,
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3506 unsigned dest_precision, signop dest_sgn)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3507 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3508 tree src_type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3509 unsigned src_precision;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3510 widest_int tem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3511 signop src_sgn;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3512
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3513 /* We can only handle integral and pointer types. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3514 src_type = vr->type ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3515 if (!INTEGRAL_TYPE_P (src_type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3516 && !POINTER_TYPE_P (src_type))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3517 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3518
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3519 /* An extension is fine unless VR is SIGNED and dest_sgn is UNSIGNED,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3520 and so is an identity transform. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3521 src_precision = TYPE_PRECISION (vr->type ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3522 src_sgn = TYPE_SIGN (src_type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3523 if ((src_precision < dest_precision
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3524 && !(dest_sgn == UNSIGNED && src_sgn == SIGNED))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3525 || (src_precision == dest_precision && src_sgn == dest_sgn))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3526 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3527
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3528 /* Now we can only handle ranges with constant bounds. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3529 if (!range_int_cst_p (vr))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3530 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3531
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3532 /* For sign changes, the MSB of the wide_int has to be clear.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3533 An unsigned value with its MSB set cannot be represented by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3534 a signed wide_int, while a negative value cannot be represented
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3535 by an unsigned wide_int. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3536 if (src_sgn != dest_sgn
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3537 && (wi::lts_p (wi::to_wide (vr->min ()), 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3538 || wi::lts_p (wi::to_wide (vr->max ()), 0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3539 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3540
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3541 /* Then we can perform the conversion on both ends and compare
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3542 the result for equality. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3543 tem = wi::ext (wi::to_widest (vr->min ()), dest_precision, dest_sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3544 if (tem != wi::to_widest (vr->min ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3545 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3546 tem = wi::ext (wi::to_widest (vr->max ()), dest_precision, dest_sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3547 if (tem != wi::to_widest (vr->max ()))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3548 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3549
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3550 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3551 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3552
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3553 /* Simplify a conditional using a relational operator to an equality
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3554 test if the range information indicates only one value can satisfy
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3555 the original conditional. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3556
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3557 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3558 vr_values::simplify_cond_using_ranges_1 (gcond *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3559 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3560 tree op0 = gimple_cond_lhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3561 tree op1 = gimple_cond_rhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3562 enum tree_code cond_code = gimple_cond_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3563
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3564 if (cond_code != NE_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3565 && cond_code != EQ_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3566 && TREE_CODE (op0) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3567 && INTEGRAL_TYPE_P (TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3568 && is_gimple_min_invariant (op1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3569 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3570 const value_range_equiv *vr = get_value_range (op0);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3571
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3572 /* If we have range information for OP0, then we might be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3573 able to simplify this conditional. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3574 if (vr->kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3575 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3576 tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3577 if (new_tree)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3578 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3579 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3580 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3581 fprintf (dump_file, "Simplified relational ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3582 print_gimple_stmt (dump_file, stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3583 fprintf (dump_file, " into ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3584 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3585
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3586 gimple_cond_set_code (stmt, EQ_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3587 gimple_cond_set_lhs (stmt, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3588 gimple_cond_set_rhs (stmt, new_tree);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3589
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3590 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3591
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3592 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3593 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3594 print_gimple_stmt (dump_file, stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3595 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3596 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3597
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3598 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3599 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3600
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3601 /* Try again after inverting the condition. We only deal
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3602 with integral types here, so no need to worry about
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3603 issues with inverting FP comparisons. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3604 new_tree = test_for_singularity
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3605 (invert_tree_comparison (cond_code, false),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3606 op0, op1, vr);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3607 if (new_tree)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3608 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3609 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3610 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3611 fprintf (dump_file, "Simplified relational ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3612 print_gimple_stmt (dump_file, stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3613 fprintf (dump_file, " into ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3614 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3615
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3616 gimple_cond_set_code (stmt, NE_EXPR);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3617 gimple_cond_set_lhs (stmt, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3618 gimple_cond_set_rhs (stmt, new_tree);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3619
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3620 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3621
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3622 if (dump_file)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3623 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3624 print_gimple_stmt (dump_file, stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3625 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3626 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3627
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3628 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3629 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3630 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3631 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3632 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3633 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3634
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3635 /* STMT is a conditional at the end of a basic block.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3636
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3637 If the conditional is of the form SSA_NAME op constant and the SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3638 was set via a type conversion, try to replace the SSA_NAME with the RHS
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3639 of the type conversion. Doing so makes the conversion dead which helps
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3640 subsequent passes. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3641
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3642 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3643 vr_values::simplify_cond_using_ranges_2 (gcond *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3644 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3645 tree op0 = gimple_cond_lhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3646 tree op1 = gimple_cond_rhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3647
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3648 /* If we have a comparison of an SSA_NAME (OP0) against a constant,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3649 see if OP0 was set by a type conversion where the source of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3650 the conversion is another SSA_NAME with a range that fits
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3651 into the range of OP0's type.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3652
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3653 If so, the conversion is redundant as the earlier SSA_NAME can be
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3654 used for the comparison directly if we just massage the constant in the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3655 comparison. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3656 if (TREE_CODE (op0) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3657 && TREE_CODE (op1) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3658 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3659 gimple *def_stmt = SSA_NAME_DEF_STMT (op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3660 tree innerop;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3661
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3662 if (!is_gimple_assign (def_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3663 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3664 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3665
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3666 innerop = gimple_assign_rhs1 (def_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3667
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3668 if (TREE_CODE (innerop) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3669 && !POINTER_TYPE_P (TREE_TYPE (innerop))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3670 && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3671 && desired_pro_or_demotion_p (TREE_TYPE (innerop), TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3672 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3673 const value_range_equiv *vr = get_value_range (innerop);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3674
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3675 if (range_int_cst_p (vr)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3676 && range_fits_type_p (vr,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3677 TYPE_PRECISION (TREE_TYPE (op0)),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3678 TYPE_SIGN (TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3679 && int_fits_type_p (op1, TREE_TYPE (innerop)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3680 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3681 tree newconst = fold_convert (TREE_TYPE (innerop), op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3682 gimple_cond_set_lhs (stmt, innerop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3683 gimple_cond_set_rhs (stmt, newconst);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3684 update_stmt (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3685 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3686 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3687 fprintf (dump_file, "Folded into: ");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3688 print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3689 fprintf (dump_file, "\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3690 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3691 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3692 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3693 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3694 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3695
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3696 /* Simplify a switch statement using the value range of the switch
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3697 argument. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3698
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3699 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3700 vr_values::simplify_switch_using_ranges (gswitch *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3701 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3702 tree op = gimple_switch_index (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
3703 const value_range_equiv *vr = NULL;
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3704 bool take_default;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3705 edge e;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3706 edge_iterator ei;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3707 size_t i = 0, j = 0, n, n2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3708 tree vec2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3709 switch_update su;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3710 size_t k = 1, l = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3711
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3712 if (TREE_CODE (op) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3713 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3714 vr = get_value_range (op);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3715
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3716 /* We can only handle integer ranges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3717 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3718 || vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3719 || vr->symbolic_p ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3720 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3721
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3722 /* Find case label for min/max of the value range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3723 take_default = !find_case_label_ranges (stmt, vr, &i, &j, &k, &l);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3724 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3725 else if (TREE_CODE (op) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3726 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3727 take_default = !find_case_label_index (stmt, 1, op, &i);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3728 if (take_default)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3729 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3730 i = 1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3731 j = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3732 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3733 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3734 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3735 j = i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3736 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3737 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3738 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3739 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3740
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3741 n = gimple_switch_num_labels (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3742
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3743 /* We can truncate the case label ranges that partially overlap with OP's
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3744 value range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3745 size_t min_idx = 1, max_idx = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3746 if (vr != NULL)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3747 find_case_label_range (stmt, vr->min (), vr->max (), &min_idx, &max_idx);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3748 if (min_idx <= max_idx)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3749 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3750 tree min_label = gimple_switch_label (stmt, min_idx);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3751 tree max_label = gimple_switch_label (stmt, max_idx);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3752
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3753 /* Avoid changing the type of the case labels when truncating. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3754 tree case_label_type = TREE_TYPE (CASE_LOW (min_label));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3755 tree vr_min = fold_convert (case_label_type, vr->min ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3756 tree vr_max = fold_convert (case_label_type, vr->max ());
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3757
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3758 if (vr->kind () == VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3759 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3760 /* If OP's value range is [2,8] and the low label range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3761 0 ... 3, truncate the label's range to 2 .. 3. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3762 if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3763 && CASE_HIGH (min_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3764 && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3765 CASE_LOW (min_label) = vr_min;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3766
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3767 /* If OP's value range is [2,8] and the high label range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3768 7 ... 10, truncate the label's range to 7 .. 8. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3769 if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3770 && CASE_HIGH (max_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3771 && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3772 CASE_HIGH (max_label) = vr_max;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3773 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3774 else if (vr->kind () == VR_ANTI_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3775 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3776 tree one_cst = build_one_cst (case_label_type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3777
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3778 if (min_label == max_label)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3779 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3780 /* If OP's value range is ~[7,8] and the label's range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3781 7 ... 10, truncate the label's range to 9 ... 10. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3782 if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) == 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3783 && CASE_HIGH (min_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3784 && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3785 CASE_LOW (min_label)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3786 = int_const_binop (PLUS_EXPR, vr_max, one_cst);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3787
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3788 /* If OP's value range is ~[7,8] and the label's range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3789 5 ... 8, truncate the label's range to 5 ... 6. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3790 if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3791 && CASE_HIGH (min_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3792 && tree_int_cst_compare (CASE_HIGH (min_label), vr_max) == 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3793 CASE_HIGH (min_label)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3794 = int_const_binop (MINUS_EXPR, vr_min, one_cst);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3795 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3796 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3797 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3798 /* If OP's value range is ~[2,8] and the low label range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3799 0 ... 3, truncate the label's range to 0 ... 1. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3800 if (tree_int_cst_compare (CASE_LOW (min_label), vr_min) < 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3801 && CASE_HIGH (min_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3802 && tree_int_cst_compare (CASE_HIGH (min_label), vr_min) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3803 CASE_HIGH (min_label)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3804 = int_const_binop (MINUS_EXPR, vr_min, one_cst);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3805
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3806 /* If OP's value range is ~[2,8] and the high label range is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3807 7 ... 10, truncate the label's range to 9 ... 10. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3808 if (tree_int_cst_compare (CASE_LOW (max_label), vr_max) <= 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3809 && CASE_HIGH (max_label) != NULL_TREE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3810 && tree_int_cst_compare (CASE_HIGH (max_label), vr_max) > 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3811 CASE_LOW (max_label)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3812 = int_const_binop (PLUS_EXPR, vr_max, one_cst);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3813 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3814 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3815
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3816 /* Canonicalize singleton case ranges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3817 if (tree_int_cst_equal (CASE_LOW (min_label), CASE_HIGH (min_label)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3818 CASE_HIGH (min_label) = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3819 if (tree_int_cst_equal (CASE_LOW (max_label), CASE_HIGH (max_label)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3820 CASE_HIGH (max_label) = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3821 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3822
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3823 /* We can also eliminate case labels that lie completely outside OP's value
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3824 range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3825
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3826 /* Bail out if this is just all edges taken. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3827 if (i == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3828 && j == n - 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3829 && take_default)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3830 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3831
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3832 /* Build a new vector of taken case labels. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3833 vec2 = make_tree_vec (j - i + 1 + l - k + 1 + (int)take_default);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3834 n2 = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3835
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3836 /* Add the default edge, if necessary. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3837 if (take_default)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3838 TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3839
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3840 for (; i <= j; ++i, ++n2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3841 TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3842
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3843 for (; k <= l; ++k, ++n2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3844 TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, k);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3845
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3846 /* Mark needed edges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3847 for (i = 0; i < n2; ++i)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3848 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3849 e = find_edge (gimple_bb (stmt),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3850 label_to_block (cfun,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3851 CASE_LABEL (TREE_VEC_ELT (vec2, i))));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3852 e->aux = (void *)-1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3853 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3854
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3855 /* Queue not needed edges for later removal. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3856 FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3857 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3858 if (e->aux == (void *)-1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3859 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3860 e->aux = NULL;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3861 continue;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3862 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3863
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3864 if (dump_file && (dump_flags & TDF_DETAILS))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3865 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3866 fprintf (dump_file, "removing unreachable case label\n");
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3867 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3868 to_remove_edges.safe_push (e);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3869 e->flags &= ~EDGE_EXECUTABLE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3870 e->flags |= EDGE_IGNORE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3871 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3872
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3873 /* And queue an update for the stmt. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3874 su.stmt = stmt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3875 su.vec = vec2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3876 to_update_switch_stmts.safe_push (su);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3877 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3878 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3879
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3880 void
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3881 vr_values::cleanup_edges_and_switches (void)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3882 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3883 int i;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3884 edge e;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3885 switch_update *su;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3886
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3887 /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3888 CFG in a broken state and requires a cfg_cleanup run. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3889 FOR_EACH_VEC_ELT (to_remove_edges, i, e)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3890 remove_edge (e);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3891
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3892 /* Update SWITCH_EXPR case label vector. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3893 FOR_EACH_VEC_ELT (to_update_switch_stmts, i, su)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3894 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3895 size_t j;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3896 size_t n = TREE_VEC_LENGTH (su->vec);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3897 tree label;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3898 gimple_switch_set_num_labels (su->stmt, n);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3899 for (j = 0; j < n; j++)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3900 gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3901 /* As we may have replaced the default label with a regular one
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3902 make sure to make it a real default label again. This ensures
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3903 optimal expansion. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3904 label = gimple_switch_label (su->stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3905 CASE_LOW (label) = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3906 CASE_HIGH (label) = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3907 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3908
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3909 if (!to_remove_edges.is_empty ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3910 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3911 free_dominance_info (CDI_DOMINATORS);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3912 loops_state_set (LOOPS_NEED_FIXUP);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3913 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3914
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3915 to_remove_edges.release ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3916 to_update_switch_stmts.release ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3917 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3918
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3919 /* Simplify an integral conversion from an SSA name in STMT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3920
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3921 static bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3922 simplify_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3923 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3924 tree innerop, middleop, finaltype;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3925 gimple *def_stmt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3926 signop inner_sgn, middle_sgn, final_sgn;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3927 unsigned inner_prec, middle_prec, final_prec;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3928 widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3929
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3930 finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3931 if (!INTEGRAL_TYPE_P (finaltype))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3932 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3933 middleop = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3934 def_stmt = SSA_NAME_DEF_STMT (middleop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3935 if (!is_gimple_assign (def_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3936 || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3937 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3938 innerop = gimple_assign_rhs1 (def_stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3939 if (TREE_CODE (innerop) != SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3940 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3941 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3942
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3943 /* Get the value-range of the inner operand. Use get_range_info in
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3944 case innerop was created during substitute-and-fold. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3945 wide_int imin, imax;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3946 if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3947 || get_range_info (innerop, &imin, &imax) != VR_RANGE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3948 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3949 innermin = widest_int::from (imin, TYPE_SIGN (TREE_TYPE (innerop)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3950 innermax = widest_int::from (imax, TYPE_SIGN (TREE_TYPE (innerop)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3951
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3952 /* Simulate the conversion chain to check if the result is equal if
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3953 the middle conversion is removed. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3954 inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3955 middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3956 final_prec = TYPE_PRECISION (finaltype);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3957
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3958 /* If the first conversion is not injective, the second must not
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3959 be widening. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3960 if (wi::gtu_p (innermax - innermin,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3961 wi::mask <widest_int> (middle_prec, false))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3962 && middle_prec < final_prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3963 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3964 /* We also want a medium value so that we can track the effect that
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3965 narrowing conversions with sign change have. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3966 inner_sgn = TYPE_SIGN (TREE_TYPE (innerop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3967 if (inner_sgn == UNSIGNED)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3968 innermed = wi::shifted_mask <widest_int> (1, inner_prec - 1, false);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3969 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3970 innermed = 0;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3971 if (wi::cmp (innermin, innermed, inner_sgn) >= 0
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3972 || wi::cmp (innermed, innermax, inner_sgn) >= 0)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3973 innermed = innermin;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3974
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3975 middle_sgn = TYPE_SIGN (TREE_TYPE (middleop));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3976 middlemin = wi::ext (innermin, middle_prec, middle_sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3977 middlemed = wi::ext (innermed, middle_prec, middle_sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3978 middlemax = wi::ext (innermax, middle_prec, middle_sgn);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3979
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3980 /* Require that the final conversion applied to both the original
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3981 and the intermediate range produces the same result. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3982 final_sgn = TYPE_SIGN (finaltype);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3983 if (wi::ext (middlemin, final_prec, final_sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3984 != wi::ext (innermin, final_prec, final_sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3985 || wi::ext (middlemed, final_prec, final_sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3986 != wi::ext (innermed, final_prec, final_sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3987 || wi::ext (middlemax, final_prec, final_sgn)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3988 != wi::ext (innermax, final_prec, final_sgn))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3989 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3990
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3991 gimple_assign_set_rhs1 (stmt, innerop);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3992 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3993 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3994 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3995
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3996 /* Simplify a conversion from integral SSA name to float in STMT. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3997
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3998 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3999 vr_values::simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4000 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4001 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4002 tree rhs1 = gimple_assign_rhs1 (stmt);
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4003 const value_range_equiv *vr = get_value_range (rhs1);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4004 scalar_float_mode fltmode
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4005 = SCALAR_FLOAT_TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4006 scalar_int_mode mode;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4007 tree tem;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4008 gassign *conv;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4009
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4010 /* We can only handle constant ranges. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4011 if (!range_int_cst_p (vr))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4012 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4013
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4014 /* First check if we can use a signed type in place of an unsigned. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4015 scalar_int_mode rhs_mode = SCALAR_INT_TYPE_MODE (TREE_TYPE (rhs1));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4016 if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4017 && can_float_p (fltmode, rhs_mode, 0) != CODE_FOR_nothing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4018 && range_fits_type_p (vr, TYPE_PRECISION (TREE_TYPE (rhs1)), SIGNED))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4019 mode = rhs_mode;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4020 /* If we can do the conversion in the current input mode do nothing. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4021 else if (can_float_p (fltmode, rhs_mode,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4022 TYPE_UNSIGNED (TREE_TYPE (rhs1))) != CODE_FOR_nothing)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4023 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4024 /* Otherwise search for a mode we can use, starting from the narrowest
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4025 integer mode available. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4026 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4027 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4028 mode = NARROWEST_INT_MODE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4029 for (;;)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4030 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4031 /* If we cannot do a signed conversion to float from mode
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4032 or if the value-range does not fit in the signed type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4033 try with a wider mode. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4034 if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4035 && range_fits_type_p (vr, GET_MODE_PRECISION (mode), SIGNED))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4036 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4037
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4038 /* But do not widen the input. Instead leave that to the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4039 optabs expansion code. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4040 if (!GET_MODE_WIDER_MODE (mode).exists (&mode)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4041 || GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4042 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4043 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4044 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4045
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4046 /* It works, insert a truncation or sign-change before the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4047 float conversion. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4048 tem = make_ssa_name (build_nonstandard_integer_type
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4049 (GET_MODE_PRECISION (mode), 0));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4050 conv = gimple_build_assign (tem, NOP_EXPR, rhs1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4051 gsi_insert_before (gsi, conv, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4052 gimple_assign_set_rhs1 (stmt, tem);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4053 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4054
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4055 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4056 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4057
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4058 /* Simplify an internal fn call using ranges if possible. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4059
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4060 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4061 vr_values::simplify_internal_call_using_ranges (gimple_stmt_iterator *gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4062 gimple *stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4063 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4064 enum tree_code subcode;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4065 bool is_ubsan = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4066 bool ovf = false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4067 switch (gimple_call_internal_fn (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4068 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4069 case IFN_UBSAN_CHECK_ADD:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4070 subcode = PLUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4071 is_ubsan = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4072 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4073 case IFN_UBSAN_CHECK_SUB:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4074 subcode = MINUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4075 is_ubsan = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4076 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4077 case IFN_UBSAN_CHECK_MUL:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4078 subcode = MULT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4079 is_ubsan = true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4080 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4081 case IFN_ADD_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4082 subcode = PLUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4083 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4084 case IFN_SUB_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4085 subcode = MINUS_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4086 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4087 case IFN_MUL_OVERFLOW:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4088 subcode = MULT_EXPR;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4089 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4090 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4091 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4092 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4093
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4094 tree op0 = gimple_call_arg (stmt, 0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4095 tree op1 = gimple_call_arg (stmt, 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4096 tree type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4097 if (is_ubsan)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4098 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4099 type = TREE_TYPE (op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4100 if (VECTOR_TYPE_P (type))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4101 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4102 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4103 else if (gimple_call_lhs (stmt) == NULL_TREE)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4104 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4105 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4106 type = TREE_TYPE (TREE_TYPE (gimple_call_lhs (stmt)));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4107 if (!check_for_binary_op_overflow (subcode, type, op0, op1, &ovf)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4108 || (is_ubsan && ovf))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4109 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4110
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4111 gimple *g;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4112 location_t loc = gimple_location (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4113 if (is_ubsan)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4114 g = gimple_build_assign (gimple_call_lhs (stmt), subcode, op0, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4115 else
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4116 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4117 int prec = TYPE_PRECISION (type);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4118 tree utype = type;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4119 if (ovf
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4120 || !useless_type_conversion_p (type, TREE_TYPE (op0))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4121 || !useless_type_conversion_p (type, TREE_TYPE (op1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4122 utype = build_nonstandard_integer_type (prec, 1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4123 if (TREE_CODE (op0) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4124 op0 = fold_convert (utype, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4125 else if (!useless_type_conversion_p (utype, TREE_TYPE (op0)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4126 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4127 g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op0);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4128 gimple_set_location (g, loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4129 gsi_insert_before (gsi, g, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4130 op0 = gimple_assign_lhs (g);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4131 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4132 if (TREE_CODE (op1) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4133 op1 = fold_convert (utype, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4134 else if (!useless_type_conversion_p (utype, TREE_TYPE (op1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4135 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4136 g = gimple_build_assign (make_ssa_name (utype), NOP_EXPR, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4137 gimple_set_location (g, loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4138 gsi_insert_before (gsi, g, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4139 op1 = gimple_assign_lhs (g);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4140 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4141 g = gimple_build_assign (make_ssa_name (utype), subcode, op0, op1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4142 gimple_set_location (g, loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4143 gsi_insert_before (gsi, g, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4144 if (utype != type)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4145 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4146 g = gimple_build_assign (make_ssa_name (type), NOP_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4147 gimple_assign_lhs (g));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4148 gimple_set_location (g, loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4149 gsi_insert_before (gsi, g, GSI_SAME_STMT);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4150 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4151 g = gimple_build_assign (gimple_call_lhs (stmt), COMPLEX_EXPR,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4152 gimple_assign_lhs (g),
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4153 build_int_cst (type, ovf));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4154 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4155 gimple_set_location (g, loc);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4156 gsi_replace (gsi, g, false);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4157 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4158 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4159
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4160 /* Return true if VAR is a two-valued variable. Set a and b with the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4161 two-values when it is true. Return false otherwise. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4162
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4163 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4164 vr_values::two_valued_val_range_p (tree var, tree *a, tree *b)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4165 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4166 const value_range_equiv *vr = get_value_range (var);
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4167 if (vr->varying_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4168 || vr->undefined_p ()
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4169 || TREE_CODE (vr->min ()) != INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4170 || TREE_CODE (vr->max ()) != INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4171 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4172
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4173 if (vr->kind () == VR_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4174 && wi::to_wide (vr->max ()) - wi::to_wide (vr->min ()) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4175 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4176 *a = vr->min ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4177 *b = vr->max ();
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4178 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4179 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4180
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4181 /* ~[TYPE_MIN + 1, TYPE_MAX - 1] */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4182 if (vr->kind () == VR_ANTI_RANGE
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4183 && (wi::to_wide (vr->min ())
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4184 - wi::to_wide (vrp_val_min (TREE_TYPE (var)))) == 1
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4185 && (wi::to_wide (vrp_val_max (TREE_TYPE (var)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4186 - wi::to_wide (vr->max ())) == 1)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4187 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4188 *a = vrp_val_min (TREE_TYPE (var));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4189 *b = vrp_val_max (TREE_TYPE (var));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4190 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4191 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4192
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4193 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4194 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4195
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4196 /* Simplify STMT using ranges if possible. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4197
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4198 bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4199 vr_values::simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4200 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4201 gimple *stmt = gsi_stmt (*gsi);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4202 if (is_gimple_assign (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4203 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4204 enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4205 tree rhs1 = gimple_assign_rhs1 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4206 tree rhs2 = gimple_assign_rhs2 (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4207 tree lhs = gimple_assign_lhs (stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4208 tree val1 = NULL_TREE, val2 = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4209 use_operand_p use_p;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4210 gimple *use_stmt;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4211
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4212 /* Convert:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4213 LHS = CST BINOP VAR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4214 Where VAR is two-valued and LHS is used in GIMPLE_COND only
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4215 To:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4216 LHS = VAR == VAL1 ? (CST BINOP VAL1) : (CST BINOP VAL2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4217
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4218 Also handles:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4219 LHS = VAR BINOP CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4220 Where VAR is two-valued and LHS is used in GIMPLE_COND only
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4221 To:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4222 LHS = VAR == VAL1 ? (VAL1 BINOP CST) : (VAL2 BINOP CST) */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4223
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4224 if (TREE_CODE_CLASS (rhs_code) == tcc_binary
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4225 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4226 && ((TREE_CODE (rhs1) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4227 && TREE_CODE (rhs2) == SSA_NAME)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4228 || (TREE_CODE (rhs2) == INTEGER_CST
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4229 && TREE_CODE (rhs1) == SSA_NAME))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4230 && single_imm_use (lhs, &use_p, &use_stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4231 && gimple_code (use_stmt) == GIMPLE_COND)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4232
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4233 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4234 tree new_rhs1 = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4235 tree new_rhs2 = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4236 tree cmp_var = NULL_TREE;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4237
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4238 if (TREE_CODE (rhs2) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4239 && two_valued_val_range_p (rhs2, &val1, &val2))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4240 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4241 /* Optimize RHS1 OP [VAL1, VAL2]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4242 new_rhs1 = int_const_binop (rhs_code, rhs1, val1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4243 new_rhs2 = int_const_binop (rhs_code, rhs1, val2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4244 cmp_var = rhs2;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4245 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4246 else if (TREE_CODE (rhs1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4247 && two_valued_val_range_p (rhs1, &val1, &val2))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4248 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4249 /* Optimize [VAL1, VAL2] OP RHS2. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4250 new_rhs1 = int_const_binop (rhs_code, val1, rhs2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4251 new_rhs2 = int_const_binop (rhs_code, val2, rhs2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4252 cmp_var = rhs1;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4253 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4254
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4255 /* If we could not find two-vals or the optimzation is invalid as
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4256 in divide by zero, new_rhs1 / new_rhs will be NULL_TREE. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4257 if (new_rhs1 && new_rhs2)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4258 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4259 tree cond = build2 (EQ_EXPR, boolean_type_node, cmp_var, val1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4260 gimple_assign_set_rhs_with_ops (gsi,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4261 COND_EXPR, cond,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4262 new_rhs1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4263 new_rhs2);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4264 update_stmt (gsi_stmt (*gsi));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4265 fold_stmt (gsi, follow_single_use_edges);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4266 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4267 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4268 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4269
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4270 switch (rhs_code)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4271 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4272 case EQ_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4273 case NE_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4274 /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4275 if the RHS is zero or one, and the LHS are known to be boolean
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4276 values. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4277 if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4278 return simplify_truth_ops_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4279 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4280
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4281 /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4282 and BIT_AND_EXPR respectively if the first operand is greater
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4283 than zero and the second operand is an exact power of two.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4284 Also optimize TRUNC_MOD_EXPR away if the second operand is
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4285 constant and the first operand already has the right value
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4286 range. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4287 case TRUNC_DIV_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4288 case TRUNC_MOD_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4289 if ((TREE_CODE (rhs1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4290 || TREE_CODE (rhs1) == INTEGER_CST)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4291 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4292 return simplify_div_or_mod_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4293 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4294
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4295 /* Transform ABS (X) into X or -X as appropriate. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4296 case ABS_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4297 if (TREE_CODE (rhs1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4298 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4299 return simplify_abs_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4300 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4301
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4302 case BIT_AND_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4303 case BIT_IOR_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4304 /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4305 if all the bits being cleared are already cleared or
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4306 all the bits being set are already set. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4307 if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4308 return simplify_bit_ops_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4309 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4310
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4311 CASE_CONVERT:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4312 if (TREE_CODE (rhs1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4313 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4314 return simplify_conversion_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4315 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4316
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4317 case FLOAT_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4318 if (TREE_CODE (rhs1) == SSA_NAME
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4319 && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4320 return simplify_float_conversion_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4321 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4322
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4323 case MIN_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4324 case MAX_EXPR:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4325 return simplify_min_or_max_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4326
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4327 default:
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4328 break;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4329 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4330 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4331 else if (gimple_code (stmt) == GIMPLE_COND)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4332 return simplify_cond_using_ranges_1 (as_a <gcond *> (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4333 else if (gimple_code (stmt) == GIMPLE_SWITCH)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4334 return simplify_switch_using_ranges (as_a <gswitch *> (stmt));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4335 else if (is_gimple_call (stmt)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4336 && gimple_call_internal_p (stmt))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4337 return simplify_internal_call_using_ranges (gsi, stmt);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4338
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4339 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4340 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4341
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4342 /* Set the lattice entry for VAR to VR. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4343
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4344 void
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4345 vr_values::set_vr_value (tree var, value_range_equiv *vr)
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4346 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4347 if (SSA_NAME_VERSION (var) >= num_vr_values)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4348 return;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4349 vr_value[SSA_NAME_VERSION (var)] = vr;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4350 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4351
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4352 /* Swap the lattice entry for VAR with VR and return the old entry. */
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4353
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4354 value_range_equiv *
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4355 vr_values::swap_vr_value (tree var, value_range_equiv *vr)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4356 {
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4357 if (SSA_NAME_VERSION (var) >= num_vr_values)
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4358 return NULL;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4359 std::swap (vr_value[SSA_NAME_VERSION (var)], vr);
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4360 return vr;
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
4361 }