xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-vrp.c (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino /* Support routines for Value Range Propagation (VRP).
2e4b17023SJohn Marino    Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
3e4b17023SJohn Marino    Free Software Foundation, Inc.
4e4b17023SJohn Marino    Contributed by Diego Novillo <dnovillo@redhat.com>.
5e4b17023SJohn Marino 
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino 
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11e4b17023SJohn Marino any later version.
12e4b17023SJohn Marino 
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e4b17023SJohn Marino GNU General Public License for more details.
17e4b17023SJohn Marino 
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21e4b17023SJohn Marino 
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "tm.h"
26e4b17023SJohn Marino #include "ggc.h"
27e4b17023SJohn Marino #include "flags.h"
28e4b17023SJohn Marino #include "tree.h"
29e4b17023SJohn Marino #include "basic-block.h"
30e4b17023SJohn Marino #include "tree-flow.h"
31e4b17023SJohn Marino #include "tree-pass.h"
32e4b17023SJohn Marino #include "tree-dump.h"
33e4b17023SJohn Marino #include "timevar.h"
34e4b17023SJohn Marino #include "tree-pretty-print.h"
35e4b17023SJohn Marino #include "gimple-pretty-print.h"
36e4b17023SJohn Marino #include "diagnostic-core.h"
37e4b17023SJohn Marino #include "intl.h"
38e4b17023SJohn Marino #include "cfgloop.h"
39e4b17023SJohn Marino #include "tree-scalar-evolution.h"
40e4b17023SJohn Marino #include "tree-ssa-propagate.h"
41e4b17023SJohn Marino #include "tree-chrec.h"
42e4b17023SJohn Marino #include "gimple-fold.h"
43e4b17023SJohn Marino #include "expr.h"
44e4b17023SJohn Marino #include "optabs.h"
45e4b17023SJohn Marino 
46e4b17023SJohn Marino 
47e4b17023SJohn Marino /* Type of value ranges.  See value_range_d for a description of these
48e4b17023SJohn Marino    types.  */
49e4b17023SJohn Marino enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
50e4b17023SJohn Marino 
51e4b17023SJohn Marino /* Range of values that can be associated with an SSA_NAME after VRP
52e4b17023SJohn Marino    has executed.  */
53e4b17023SJohn Marino struct value_range_d
54e4b17023SJohn Marino {
55e4b17023SJohn Marino   /* Lattice value represented by this range.  */
56e4b17023SJohn Marino   enum value_range_type type;
57e4b17023SJohn Marino 
58e4b17023SJohn Marino   /* Minimum and maximum values represented by this range.  These
59e4b17023SJohn Marino      values should be interpreted as follows:
60e4b17023SJohn Marino 
61e4b17023SJohn Marino 	- If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
62e4b17023SJohn Marino 	  be NULL.
63e4b17023SJohn Marino 
64e4b17023SJohn Marino 	- If TYPE == VR_RANGE then MIN holds the minimum value and
65e4b17023SJohn Marino 	  MAX holds the maximum value of the range [MIN, MAX].
66e4b17023SJohn Marino 
67e4b17023SJohn Marino 	- If TYPE == ANTI_RANGE the variable is known to NOT
68e4b17023SJohn Marino 	  take any values in the range [MIN, MAX].  */
69e4b17023SJohn Marino   tree min;
70e4b17023SJohn Marino   tree max;
71e4b17023SJohn Marino 
72e4b17023SJohn Marino   /* Set of SSA names whose value ranges are equivalent to this one.
73e4b17023SJohn Marino      This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
74e4b17023SJohn Marino   bitmap equiv;
75e4b17023SJohn Marino };
76e4b17023SJohn Marino 
77e4b17023SJohn Marino typedef struct value_range_d value_range_t;
78e4b17023SJohn Marino 
79e4b17023SJohn Marino /* Set of SSA names found live during the RPO traversal of the function
80e4b17023SJohn Marino    for still active basic-blocks.  */
81e4b17023SJohn Marino static sbitmap *live;
82e4b17023SJohn Marino 
83e4b17023SJohn Marino /* Return true if the SSA name NAME is live on the edge E.  */
84e4b17023SJohn Marino 
85e4b17023SJohn Marino static bool
live_on_edge(edge e,tree name)86e4b17023SJohn Marino live_on_edge (edge e, tree name)
87e4b17023SJohn Marino {
88e4b17023SJohn Marino   return (live[e->dest->index]
89e4b17023SJohn Marino 	  && TEST_BIT (live[e->dest->index], SSA_NAME_VERSION (name)));
90e4b17023SJohn Marino }
91e4b17023SJohn Marino 
92e4b17023SJohn Marino /* Local functions.  */
93e4b17023SJohn Marino static int compare_values (tree val1, tree val2);
94e4b17023SJohn Marino static int compare_values_warnv (tree val1, tree val2, bool *);
95e4b17023SJohn Marino static void vrp_meet (value_range_t *, value_range_t *);
96e4b17023SJohn Marino static tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
97e4b17023SJohn Marino 						     tree, tree, bool, bool *,
98e4b17023SJohn Marino 						     bool *);
99e4b17023SJohn Marino 
100e4b17023SJohn Marino /* Location information for ASSERT_EXPRs.  Each instance of this
101e4b17023SJohn Marino    structure describes an ASSERT_EXPR for an SSA name.  Since a single
102e4b17023SJohn Marino    SSA name may have more than one assertion associated with it, these
103e4b17023SJohn Marino    locations are kept in a linked list attached to the corresponding
104e4b17023SJohn Marino    SSA name.  */
105e4b17023SJohn Marino struct assert_locus_d
106e4b17023SJohn Marino {
107e4b17023SJohn Marino   /* Basic block where the assertion would be inserted.  */
108e4b17023SJohn Marino   basic_block bb;
109e4b17023SJohn Marino 
110e4b17023SJohn Marino   /* Some assertions need to be inserted on an edge (e.g., assertions
111e4b17023SJohn Marino      generated by COND_EXPRs).  In those cases, BB will be NULL.  */
112e4b17023SJohn Marino   edge e;
113e4b17023SJohn Marino 
114e4b17023SJohn Marino   /* Pointer to the statement that generated this assertion.  */
115e4b17023SJohn Marino   gimple_stmt_iterator si;
116e4b17023SJohn Marino 
117e4b17023SJohn Marino   /* Predicate code for the ASSERT_EXPR.  Must be COMPARISON_CLASS_P.  */
118e4b17023SJohn Marino   enum tree_code comp_code;
119e4b17023SJohn Marino 
120e4b17023SJohn Marino   /* Value being compared against.  */
121e4b17023SJohn Marino   tree val;
122e4b17023SJohn Marino 
123e4b17023SJohn Marino   /* Expression to compare.  */
124e4b17023SJohn Marino   tree expr;
125e4b17023SJohn Marino 
126e4b17023SJohn Marino   /* Next node in the linked list.  */
127e4b17023SJohn Marino   struct assert_locus_d *next;
128e4b17023SJohn Marino };
129e4b17023SJohn Marino 
130e4b17023SJohn Marino typedef struct assert_locus_d *assert_locus_t;
131e4b17023SJohn Marino 
132e4b17023SJohn Marino /* If bit I is present, it means that SSA name N_i has a list of
133e4b17023SJohn Marino    assertions that should be inserted in the IL.  */
134e4b17023SJohn Marino static bitmap need_assert_for;
135e4b17023SJohn Marino 
136e4b17023SJohn Marino /* Array of locations lists where to insert assertions.  ASSERTS_FOR[I]
137e4b17023SJohn Marino    holds a list of ASSERT_LOCUS_T nodes that describe where
138e4b17023SJohn Marino    ASSERT_EXPRs for SSA name N_I should be inserted.  */
139e4b17023SJohn Marino static assert_locus_t *asserts_for;
140e4b17023SJohn Marino 
141e4b17023SJohn Marino /* Value range array.  After propagation, VR_VALUE[I] holds the range
142e4b17023SJohn Marino    of values that SSA name N_I may take.  */
143e4b17023SJohn Marino static unsigned num_vr_values;
144e4b17023SJohn Marino static value_range_t **vr_value;
145e4b17023SJohn Marino static bool values_propagated;
146e4b17023SJohn Marino 
147e4b17023SJohn Marino /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
148e4b17023SJohn Marino    number of executable edges we saw the last time we visited the
149e4b17023SJohn Marino    node.  */
150e4b17023SJohn Marino static int *vr_phi_edge_counts;
151e4b17023SJohn Marino 
152e4b17023SJohn Marino typedef struct {
153e4b17023SJohn Marino   gimple stmt;
154e4b17023SJohn Marino   tree vec;
155e4b17023SJohn Marino } switch_update;
156e4b17023SJohn Marino 
157e4b17023SJohn Marino static VEC (edge, heap) *to_remove_edges;
158e4b17023SJohn Marino DEF_VEC_O(switch_update);
159e4b17023SJohn Marino DEF_VEC_ALLOC_O(switch_update, heap);
VEC(switch_update,heap)160e4b17023SJohn Marino static VEC (switch_update, heap) *to_update_switch_stmts;
161e4b17023SJohn Marino 
162e4b17023SJohn Marino 
163e4b17023SJohn Marino /* Return the maximum value for TYPE.  */
164e4b17023SJohn Marino 
165e4b17023SJohn Marino static inline tree
166e4b17023SJohn Marino vrp_val_max (const_tree type)
167e4b17023SJohn Marino {
168e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (type))
169e4b17023SJohn Marino     return NULL_TREE;
170e4b17023SJohn Marino 
171e4b17023SJohn Marino   return TYPE_MAX_VALUE (type);
172e4b17023SJohn Marino }
173e4b17023SJohn Marino 
174e4b17023SJohn Marino /* Return the minimum value for TYPE.  */
175e4b17023SJohn Marino 
176e4b17023SJohn Marino static inline tree
vrp_val_min(const_tree type)177e4b17023SJohn Marino vrp_val_min (const_tree type)
178e4b17023SJohn Marino {
179e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (type))
180e4b17023SJohn Marino     return NULL_TREE;
181e4b17023SJohn Marino 
182e4b17023SJohn Marino   return TYPE_MIN_VALUE (type);
183e4b17023SJohn Marino }
184e4b17023SJohn Marino 
185e4b17023SJohn Marino /* Return whether VAL is equal to the maximum value of its type.  This
186e4b17023SJohn Marino    will be true for a positive overflow infinity.  We can't do a
187e4b17023SJohn Marino    simple equality comparison with TYPE_MAX_VALUE because C typedefs
188e4b17023SJohn Marino    and Ada subtypes can produce types whose TYPE_MAX_VALUE is not ==
189e4b17023SJohn Marino    to the integer constant with the same value in the type.  */
190e4b17023SJohn Marino 
191e4b17023SJohn Marino static inline bool
vrp_val_is_max(const_tree val)192e4b17023SJohn Marino vrp_val_is_max (const_tree val)
193e4b17023SJohn Marino {
194e4b17023SJohn Marino   tree type_max = vrp_val_max (TREE_TYPE (val));
195e4b17023SJohn Marino   return (val == type_max
196e4b17023SJohn Marino 	  || (type_max != NULL_TREE
197e4b17023SJohn Marino 	      && operand_equal_p (val, type_max, 0)));
198e4b17023SJohn Marino }
199e4b17023SJohn Marino 
200e4b17023SJohn Marino /* Return whether VAL is equal to the minimum value of its type.  This
201e4b17023SJohn Marino    will be true for a negative overflow infinity.  */
202e4b17023SJohn Marino 
203e4b17023SJohn Marino static inline bool
vrp_val_is_min(const_tree val)204e4b17023SJohn Marino vrp_val_is_min (const_tree val)
205e4b17023SJohn Marino {
206e4b17023SJohn Marino   tree type_min = vrp_val_min (TREE_TYPE (val));
207e4b17023SJohn Marino   return (val == type_min
208e4b17023SJohn Marino 	  || (type_min != NULL_TREE
209e4b17023SJohn Marino 	      && operand_equal_p (val, type_min, 0)));
210e4b17023SJohn Marino }
211e4b17023SJohn Marino 
212e4b17023SJohn Marino 
213e4b17023SJohn Marino /* Return whether TYPE should use an overflow infinity distinct from
214e4b17023SJohn Marino    TYPE_{MIN,MAX}_VALUE.  We use an overflow infinity value to
215e4b17023SJohn Marino    represent a signed overflow during VRP computations.  An infinity
216e4b17023SJohn Marino    is distinct from a half-range, which will go from some number to
217e4b17023SJohn Marino    TYPE_{MIN,MAX}_VALUE.  */
218e4b17023SJohn Marino 
219e4b17023SJohn Marino static inline bool
needs_overflow_infinity(const_tree type)220e4b17023SJohn Marino needs_overflow_infinity (const_tree type)
221e4b17023SJohn Marino {
222e4b17023SJohn Marino   return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
223e4b17023SJohn Marino }
224e4b17023SJohn Marino 
225e4b17023SJohn Marino /* Return whether TYPE can support our overflow infinity
226e4b17023SJohn Marino    representation: we use the TREE_OVERFLOW flag, which only exists
227e4b17023SJohn Marino    for constants.  If TYPE doesn't support this, we don't optimize
228e4b17023SJohn Marino    cases which would require signed overflow--we drop them to
229e4b17023SJohn Marino    VARYING.  */
230e4b17023SJohn Marino 
231e4b17023SJohn Marino static inline bool
supports_overflow_infinity(const_tree type)232e4b17023SJohn Marino supports_overflow_infinity (const_tree type)
233e4b17023SJohn Marino {
234e4b17023SJohn Marino   tree min = vrp_val_min (type), max = vrp_val_max (type);
235e4b17023SJohn Marino #ifdef ENABLE_CHECKING
236e4b17023SJohn Marino   gcc_assert (needs_overflow_infinity (type));
237e4b17023SJohn Marino #endif
238e4b17023SJohn Marino   return (min != NULL_TREE
239e4b17023SJohn Marino 	  && CONSTANT_CLASS_P (min)
240e4b17023SJohn Marino 	  && max != NULL_TREE
241e4b17023SJohn Marino 	  && CONSTANT_CLASS_P (max));
242e4b17023SJohn Marino }
243e4b17023SJohn Marino 
244e4b17023SJohn Marino /* VAL is the maximum or minimum value of a type.  Return a
245e4b17023SJohn Marino    corresponding overflow infinity.  */
246e4b17023SJohn Marino 
247e4b17023SJohn Marino static inline tree
make_overflow_infinity(tree val)248e4b17023SJohn Marino make_overflow_infinity (tree val)
249e4b17023SJohn Marino {
250e4b17023SJohn Marino   gcc_checking_assert (val != NULL_TREE && CONSTANT_CLASS_P (val));
251e4b17023SJohn Marino   val = copy_node (val);
252e4b17023SJohn Marino   TREE_OVERFLOW (val) = 1;
253e4b17023SJohn Marino   return val;
254e4b17023SJohn Marino }
255e4b17023SJohn Marino 
256e4b17023SJohn Marino /* Return a negative overflow infinity for TYPE.  */
257e4b17023SJohn Marino 
258e4b17023SJohn Marino static inline tree
negative_overflow_infinity(tree type)259e4b17023SJohn Marino negative_overflow_infinity (tree type)
260e4b17023SJohn Marino {
261e4b17023SJohn Marino   gcc_checking_assert (supports_overflow_infinity (type));
262e4b17023SJohn Marino   return make_overflow_infinity (vrp_val_min (type));
263e4b17023SJohn Marino }
264e4b17023SJohn Marino 
265e4b17023SJohn Marino /* Return a positive overflow infinity for TYPE.  */
266e4b17023SJohn Marino 
267e4b17023SJohn Marino static inline tree
positive_overflow_infinity(tree type)268e4b17023SJohn Marino positive_overflow_infinity (tree type)
269e4b17023SJohn Marino {
270e4b17023SJohn Marino   gcc_checking_assert (supports_overflow_infinity (type));
271e4b17023SJohn Marino   return make_overflow_infinity (vrp_val_max (type));
272e4b17023SJohn Marino }
273e4b17023SJohn Marino 
274e4b17023SJohn Marino /* Return whether VAL is a negative overflow infinity.  */
275e4b17023SJohn Marino 
276e4b17023SJohn Marino static inline bool
is_negative_overflow_infinity(const_tree val)277e4b17023SJohn Marino is_negative_overflow_infinity (const_tree val)
278e4b17023SJohn Marino {
279e4b17023SJohn Marino   return (needs_overflow_infinity (TREE_TYPE (val))
280e4b17023SJohn Marino 	  && CONSTANT_CLASS_P (val)
281e4b17023SJohn Marino 	  && TREE_OVERFLOW (val)
282e4b17023SJohn Marino 	  && vrp_val_is_min (val));
283e4b17023SJohn Marino }
284e4b17023SJohn Marino 
285e4b17023SJohn Marino /* Return whether VAL is a positive overflow infinity.  */
286e4b17023SJohn Marino 
287e4b17023SJohn Marino static inline bool
is_positive_overflow_infinity(const_tree val)288e4b17023SJohn Marino is_positive_overflow_infinity (const_tree val)
289e4b17023SJohn Marino {
290e4b17023SJohn Marino   return (needs_overflow_infinity (TREE_TYPE (val))
291e4b17023SJohn Marino 	  && CONSTANT_CLASS_P (val)
292e4b17023SJohn Marino 	  && TREE_OVERFLOW (val)
293e4b17023SJohn Marino 	  && vrp_val_is_max (val));
294e4b17023SJohn Marino }
295e4b17023SJohn Marino 
296e4b17023SJohn Marino /* Return whether VAL is a positive or negative overflow infinity.  */
297e4b17023SJohn Marino 
298e4b17023SJohn Marino static inline bool
is_overflow_infinity(const_tree val)299e4b17023SJohn Marino is_overflow_infinity (const_tree val)
300e4b17023SJohn Marino {
301e4b17023SJohn Marino   return (needs_overflow_infinity (TREE_TYPE (val))
302e4b17023SJohn Marino 	  && CONSTANT_CLASS_P (val)
303e4b17023SJohn Marino 	  && TREE_OVERFLOW (val)
304e4b17023SJohn Marino 	  && (vrp_val_is_min (val) || vrp_val_is_max (val)));
305e4b17023SJohn Marino }
306e4b17023SJohn Marino 
307e4b17023SJohn Marino /* Return whether STMT has a constant rhs that is_overflow_infinity. */
308e4b17023SJohn Marino 
309e4b17023SJohn Marino static inline bool
stmt_overflow_infinity(gimple stmt)310e4b17023SJohn Marino stmt_overflow_infinity (gimple stmt)
311e4b17023SJohn Marino {
312e4b17023SJohn Marino   if (is_gimple_assign (stmt)
313e4b17023SJohn Marino       && get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) ==
314e4b17023SJohn Marino       GIMPLE_SINGLE_RHS)
315e4b17023SJohn Marino     return is_overflow_infinity (gimple_assign_rhs1 (stmt));
316e4b17023SJohn Marino   return false;
317e4b17023SJohn Marino }
318e4b17023SJohn Marino 
319e4b17023SJohn Marino /* If VAL is now an overflow infinity, return VAL.  Otherwise, return
320e4b17023SJohn Marino    the same value with TREE_OVERFLOW clear.  This can be used to avoid
321e4b17023SJohn Marino    confusing a regular value with an overflow value.  */
322e4b17023SJohn Marino 
323e4b17023SJohn Marino static inline tree
avoid_overflow_infinity(tree val)324e4b17023SJohn Marino avoid_overflow_infinity (tree val)
325e4b17023SJohn Marino {
326e4b17023SJohn Marino   if (!is_overflow_infinity (val))
327e4b17023SJohn Marino     return val;
328e4b17023SJohn Marino 
329e4b17023SJohn Marino   if (vrp_val_is_max (val))
330e4b17023SJohn Marino     return vrp_val_max (TREE_TYPE (val));
331e4b17023SJohn Marino   else
332e4b17023SJohn Marino     {
333e4b17023SJohn Marino       gcc_checking_assert (vrp_val_is_min (val));
334e4b17023SJohn Marino       return vrp_val_min (TREE_TYPE (val));
335e4b17023SJohn Marino     }
336e4b17023SJohn Marino }
337e4b17023SJohn Marino 
338e4b17023SJohn Marino 
339e4b17023SJohn Marino /* Return true if ARG is marked with the nonnull attribute in the
340e4b17023SJohn Marino    current function signature.  */
341e4b17023SJohn Marino 
342e4b17023SJohn Marino static bool
nonnull_arg_p(const_tree arg)343e4b17023SJohn Marino nonnull_arg_p (const_tree arg)
344e4b17023SJohn Marino {
345e4b17023SJohn Marino   tree t, attrs, fntype;
346e4b17023SJohn Marino   unsigned HOST_WIDE_INT arg_num;
347e4b17023SJohn Marino 
348e4b17023SJohn Marino   gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
349e4b17023SJohn Marino 
350e4b17023SJohn Marino   /* The static chain decl is always non null.  */
351e4b17023SJohn Marino   if (arg == cfun->static_chain_decl)
352e4b17023SJohn Marino     return true;
353e4b17023SJohn Marino 
354e4b17023SJohn Marino   fntype = TREE_TYPE (current_function_decl);
355e4b17023SJohn Marino   attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
356e4b17023SJohn Marino 
357e4b17023SJohn Marino   /* If "nonnull" wasn't specified, we know nothing about the argument.  */
358e4b17023SJohn Marino   if (attrs == NULL_TREE)
359e4b17023SJohn Marino     return false;
360e4b17023SJohn Marino 
361e4b17023SJohn Marino   /* If "nonnull" applies to all the arguments, then ARG is non-null.  */
362e4b17023SJohn Marino   if (TREE_VALUE (attrs) == NULL_TREE)
363e4b17023SJohn Marino     return true;
364e4b17023SJohn Marino 
365e4b17023SJohn Marino   /* Get the position number for ARG in the function signature.  */
366e4b17023SJohn Marino   for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
367e4b17023SJohn Marino        t;
368e4b17023SJohn Marino        t = DECL_CHAIN (t), arg_num++)
369e4b17023SJohn Marino     {
370e4b17023SJohn Marino       if (t == arg)
371e4b17023SJohn Marino 	break;
372e4b17023SJohn Marino     }
373e4b17023SJohn Marino 
374e4b17023SJohn Marino   gcc_assert (t == arg);
375e4b17023SJohn Marino 
376e4b17023SJohn Marino   /* Now see if ARG_NUM is mentioned in the nonnull list.  */
377e4b17023SJohn Marino   for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
378e4b17023SJohn Marino     {
379e4b17023SJohn Marino       if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
380e4b17023SJohn Marino 	return true;
381e4b17023SJohn Marino     }
382e4b17023SJohn Marino 
383e4b17023SJohn Marino   return false;
384e4b17023SJohn Marino }
385e4b17023SJohn Marino 
386e4b17023SJohn Marino 
387e4b17023SJohn Marino /* Set value range VR to VR_VARYING.  */
388e4b17023SJohn Marino 
389e4b17023SJohn Marino static inline void
set_value_range_to_varying(value_range_t * vr)390e4b17023SJohn Marino set_value_range_to_varying (value_range_t *vr)
391e4b17023SJohn Marino {
392e4b17023SJohn Marino   vr->type = VR_VARYING;
393e4b17023SJohn Marino   vr->min = vr->max = NULL_TREE;
394e4b17023SJohn Marino   if (vr->equiv)
395e4b17023SJohn Marino     bitmap_clear (vr->equiv);
396e4b17023SJohn Marino }
397e4b17023SJohn Marino 
398e4b17023SJohn Marino 
399e4b17023SJohn Marino /* Set value range VR to {T, MIN, MAX, EQUIV}.  */
400e4b17023SJohn Marino 
401e4b17023SJohn Marino static void
set_value_range(value_range_t * vr,enum value_range_type t,tree min,tree max,bitmap equiv)402e4b17023SJohn Marino set_value_range (value_range_t *vr, enum value_range_type t, tree min,
403e4b17023SJohn Marino 		 tree max, bitmap equiv)
404e4b17023SJohn Marino {
405e4b17023SJohn Marino #if defined ENABLE_CHECKING
406e4b17023SJohn Marino   /* Check the validity of the range.  */
407e4b17023SJohn Marino   if (t == VR_RANGE || t == VR_ANTI_RANGE)
408e4b17023SJohn Marino     {
409e4b17023SJohn Marino       int cmp;
410e4b17023SJohn Marino 
411e4b17023SJohn Marino       gcc_assert (min && max);
412e4b17023SJohn Marino 
413e4b17023SJohn Marino       if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
414e4b17023SJohn Marino 	gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
415e4b17023SJohn Marino 
416e4b17023SJohn Marino       cmp = compare_values (min, max);
417e4b17023SJohn Marino       gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
418e4b17023SJohn Marino 
419e4b17023SJohn Marino       if (needs_overflow_infinity (TREE_TYPE (min)))
420e4b17023SJohn Marino 	gcc_assert (!is_overflow_infinity (min)
421e4b17023SJohn Marino 		    || !is_overflow_infinity (max));
422e4b17023SJohn Marino     }
423e4b17023SJohn Marino 
424e4b17023SJohn Marino   if (t == VR_UNDEFINED || t == VR_VARYING)
425e4b17023SJohn Marino     gcc_assert (min == NULL_TREE && max == NULL_TREE);
426e4b17023SJohn Marino 
427e4b17023SJohn Marino   if (t == VR_UNDEFINED || t == VR_VARYING)
428e4b17023SJohn Marino     gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
429e4b17023SJohn Marino #endif
430e4b17023SJohn Marino 
431e4b17023SJohn Marino   vr->type = t;
432e4b17023SJohn Marino   vr->min = min;
433e4b17023SJohn Marino   vr->max = max;
434e4b17023SJohn Marino 
435e4b17023SJohn Marino   /* Since updating the equivalence set involves deep copying the
436e4b17023SJohn Marino      bitmaps, only do it if absolutely necessary.  */
437e4b17023SJohn Marino   if (vr->equiv == NULL
438e4b17023SJohn Marino       && equiv != NULL)
439e4b17023SJohn Marino     vr->equiv = BITMAP_ALLOC (NULL);
440e4b17023SJohn Marino 
441e4b17023SJohn Marino   if (equiv != vr->equiv)
442e4b17023SJohn Marino     {
443e4b17023SJohn Marino       if (equiv && !bitmap_empty_p (equiv))
444e4b17023SJohn Marino 	bitmap_copy (vr->equiv, equiv);
445e4b17023SJohn Marino       else
446e4b17023SJohn Marino 	bitmap_clear (vr->equiv);
447e4b17023SJohn Marino     }
448e4b17023SJohn Marino }
449e4b17023SJohn Marino 
450e4b17023SJohn Marino 
451e4b17023SJohn Marino /* Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}.
452e4b17023SJohn Marino    This means adjusting T, MIN and MAX representing the case of a
453e4b17023SJohn Marino    wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
454e4b17023SJohn Marino    as anti-rage ~[MAX+1, MIN-1].  Likewise for wrapping anti-ranges.
455e4b17023SJohn Marino    In corner cases where MAX+1 or MIN-1 wraps this will fall back
456e4b17023SJohn Marino    to varying.
457e4b17023SJohn Marino    This routine exists to ease canonicalization in the case where we
458e4b17023SJohn Marino    extract ranges from var + CST op limit.  */
459e4b17023SJohn Marino 
460e4b17023SJohn Marino static void
set_and_canonicalize_value_range(value_range_t * vr,enum value_range_type t,tree min,tree max,bitmap equiv)461e4b17023SJohn Marino set_and_canonicalize_value_range (value_range_t *vr, enum value_range_type t,
462e4b17023SJohn Marino 				  tree min, tree max, bitmap equiv)
463e4b17023SJohn Marino {
464e4b17023SJohn Marino   /* Nothing to canonicalize for symbolic or unknown or varying ranges.  */
465e4b17023SJohn Marino   if ((t != VR_RANGE
466e4b17023SJohn Marino        && t != VR_ANTI_RANGE)
467e4b17023SJohn Marino       || TREE_CODE (min) != INTEGER_CST
468e4b17023SJohn Marino       || TREE_CODE (max) != INTEGER_CST)
469e4b17023SJohn Marino     {
470e4b17023SJohn Marino       set_value_range (vr, t, min, max, equiv);
471e4b17023SJohn Marino       return;
472e4b17023SJohn Marino     }
473e4b17023SJohn Marino 
474e4b17023SJohn Marino   /* Wrong order for min and max, to swap them and the VR type we need
475e4b17023SJohn Marino      to adjust them.  */
476e4b17023SJohn Marino   if (tree_int_cst_lt (max, min))
477e4b17023SJohn Marino     {
478e4b17023SJohn Marino       tree one = build_int_cst (TREE_TYPE (min), 1);
479e4b17023SJohn Marino       tree tmp = int_const_binop (PLUS_EXPR, max, one);
480e4b17023SJohn Marino       max = int_const_binop (MINUS_EXPR, min, one);
481e4b17023SJohn Marino       min = tmp;
482e4b17023SJohn Marino 
483e4b17023SJohn Marino       /* There's one corner case, if we had [C+1, C] before we now have
484e4b17023SJohn Marino 	 that again.  But this represents an empty value range, so drop
485e4b17023SJohn Marino 	 to varying in this case.  */
486e4b17023SJohn Marino       if (tree_int_cst_lt (max, min))
487e4b17023SJohn Marino 	{
488e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
489e4b17023SJohn Marino 	  return;
490e4b17023SJohn Marino 	}
491e4b17023SJohn Marino 
492e4b17023SJohn Marino       t = t == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
493e4b17023SJohn Marino     }
494e4b17023SJohn Marino 
495e4b17023SJohn Marino   /* Anti-ranges that can be represented as ranges should be so.  */
496e4b17023SJohn Marino   if (t == VR_ANTI_RANGE)
497e4b17023SJohn Marino     {
498e4b17023SJohn Marino       bool is_min = vrp_val_is_min (min);
499e4b17023SJohn Marino       bool is_max = vrp_val_is_max (max);
500e4b17023SJohn Marino 
501e4b17023SJohn Marino       if (is_min && is_max)
502e4b17023SJohn Marino 	{
503e4b17023SJohn Marino 	  /* We cannot deal with empty ranges, drop to varying.  */
504e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
505e4b17023SJohn Marino 	  return;
506e4b17023SJohn Marino 	}
507e4b17023SJohn Marino       else if (is_min
508e4b17023SJohn Marino 	       /* As a special exception preserve non-null ranges.  */
509e4b17023SJohn Marino 	       && !(TYPE_UNSIGNED (TREE_TYPE (min))
510e4b17023SJohn Marino 		    && integer_zerop (max)))
511e4b17023SJohn Marino         {
512e4b17023SJohn Marino 	  tree one = build_int_cst (TREE_TYPE (max), 1);
513e4b17023SJohn Marino 	  min = int_const_binop (PLUS_EXPR, max, one);
514e4b17023SJohn Marino 	  max = vrp_val_max (TREE_TYPE (max));
515e4b17023SJohn Marino 	  t = VR_RANGE;
516e4b17023SJohn Marino         }
517e4b17023SJohn Marino       else if (is_max)
518e4b17023SJohn Marino         {
519e4b17023SJohn Marino 	  tree one = build_int_cst (TREE_TYPE (min), 1);
520e4b17023SJohn Marino 	  max = int_const_binop (MINUS_EXPR, min, one);
521e4b17023SJohn Marino 	  min = vrp_val_min (TREE_TYPE (min));
522e4b17023SJohn Marino 	  t = VR_RANGE;
523e4b17023SJohn Marino         }
524e4b17023SJohn Marino     }
525e4b17023SJohn Marino 
526e4b17023SJohn Marino   set_value_range (vr, t, min, max, equiv);
527e4b17023SJohn Marino }
528e4b17023SJohn Marino 
529e4b17023SJohn Marino /* Copy value range FROM into value range TO.  */
530e4b17023SJohn Marino 
531e4b17023SJohn Marino static inline void
copy_value_range(value_range_t * to,value_range_t * from)532e4b17023SJohn Marino copy_value_range (value_range_t *to, value_range_t *from)
533e4b17023SJohn Marino {
534e4b17023SJohn Marino   set_value_range (to, from->type, from->min, from->max, from->equiv);
535e4b17023SJohn Marino }
536e4b17023SJohn Marino 
537e4b17023SJohn Marino /* Set value range VR to a single value.  This function is only called
538e4b17023SJohn Marino    with values we get from statements, and exists to clear the
539e4b17023SJohn Marino    TREE_OVERFLOW flag so that we don't think we have an overflow
540e4b17023SJohn Marino    infinity when we shouldn't.  */
541e4b17023SJohn Marino 
542e4b17023SJohn Marino static inline void
set_value_range_to_value(value_range_t * vr,tree val,bitmap equiv)543e4b17023SJohn Marino set_value_range_to_value (value_range_t *vr, tree val, bitmap equiv)
544e4b17023SJohn Marino {
545e4b17023SJohn Marino   gcc_assert (is_gimple_min_invariant (val));
546e4b17023SJohn Marino   val = avoid_overflow_infinity (val);
547e4b17023SJohn Marino   set_value_range (vr, VR_RANGE, val, val, equiv);
548e4b17023SJohn Marino }
549e4b17023SJohn Marino 
550e4b17023SJohn Marino /* Set value range VR to a non-negative range of type TYPE.
551e4b17023SJohn Marino    OVERFLOW_INFINITY indicates whether to use an overflow infinity
552e4b17023SJohn Marino    rather than TYPE_MAX_VALUE; this should be true if we determine
553e4b17023SJohn Marino    that the range is nonnegative based on the assumption that signed
554e4b17023SJohn Marino    overflow does not occur.  */
555e4b17023SJohn Marino 
556e4b17023SJohn Marino static inline void
set_value_range_to_nonnegative(value_range_t * vr,tree type,bool overflow_infinity)557e4b17023SJohn Marino set_value_range_to_nonnegative (value_range_t *vr, tree type,
558e4b17023SJohn Marino 				bool overflow_infinity)
559e4b17023SJohn Marino {
560e4b17023SJohn Marino   tree zero;
561e4b17023SJohn Marino 
562e4b17023SJohn Marino   if (overflow_infinity && !supports_overflow_infinity (type))
563e4b17023SJohn Marino     {
564e4b17023SJohn Marino       set_value_range_to_varying (vr);
565e4b17023SJohn Marino       return;
566e4b17023SJohn Marino     }
567e4b17023SJohn Marino 
568e4b17023SJohn Marino   zero = build_int_cst (type, 0);
569e4b17023SJohn Marino   set_value_range (vr, VR_RANGE, zero,
570e4b17023SJohn Marino 		   (overflow_infinity
571e4b17023SJohn Marino 		    ? positive_overflow_infinity (type)
572e4b17023SJohn Marino 		    : TYPE_MAX_VALUE (type)),
573e4b17023SJohn Marino 		   vr->equiv);
574e4b17023SJohn Marino }
575e4b17023SJohn Marino 
576e4b17023SJohn Marino /* Set value range VR to a non-NULL range of type TYPE.  */
577e4b17023SJohn Marino 
578e4b17023SJohn Marino static inline void
set_value_range_to_nonnull(value_range_t * vr,tree type)579e4b17023SJohn Marino set_value_range_to_nonnull (value_range_t *vr, tree type)
580e4b17023SJohn Marino {
581e4b17023SJohn Marino   tree zero = build_int_cst (type, 0);
582e4b17023SJohn Marino   set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
583e4b17023SJohn Marino }
584e4b17023SJohn Marino 
585e4b17023SJohn Marino 
586e4b17023SJohn Marino /* Set value range VR to a NULL range of type TYPE.  */
587e4b17023SJohn Marino 
588e4b17023SJohn Marino static inline void
set_value_range_to_null(value_range_t * vr,tree type)589e4b17023SJohn Marino set_value_range_to_null (value_range_t *vr, tree type)
590e4b17023SJohn Marino {
591e4b17023SJohn Marino   set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv);
592e4b17023SJohn Marino }
593e4b17023SJohn Marino 
594e4b17023SJohn Marino 
595e4b17023SJohn Marino /* Set value range VR to a range of a truthvalue of type TYPE.  */
596e4b17023SJohn Marino 
597e4b17023SJohn Marino static inline void
set_value_range_to_truthvalue(value_range_t * vr,tree type)598e4b17023SJohn Marino set_value_range_to_truthvalue (value_range_t *vr, tree type)
599e4b17023SJohn Marino {
600e4b17023SJohn Marino   if (TYPE_PRECISION (type) == 1)
601e4b17023SJohn Marino     set_value_range_to_varying (vr);
602e4b17023SJohn Marino   else
603e4b17023SJohn Marino     set_value_range (vr, VR_RANGE,
604e4b17023SJohn Marino 		     build_int_cst (type, 0), build_int_cst (type, 1),
605e4b17023SJohn Marino 		     vr->equiv);
606e4b17023SJohn Marino }
607e4b17023SJohn Marino 
608e4b17023SJohn Marino 
609e4b17023SJohn Marino /* Set value range VR to VR_UNDEFINED.  */
610e4b17023SJohn Marino 
611e4b17023SJohn Marino static inline void
set_value_range_to_undefined(value_range_t * vr)612e4b17023SJohn Marino set_value_range_to_undefined (value_range_t *vr)
613e4b17023SJohn Marino {
614e4b17023SJohn Marino   vr->type = VR_UNDEFINED;
615e4b17023SJohn Marino   vr->min = vr->max = NULL_TREE;
616e4b17023SJohn Marino   if (vr->equiv)
617e4b17023SJohn Marino     bitmap_clear (vr->equiv);
618e4b17023SJohn Marino }
619e4b17023SJohn Marino 
620e4b17023SJohn Marino 
621e4b17023SJohn Marino /* If abs (min) < abs (max), set VR to [-max, max], if
622e4b17023SJohn Marino    abs (min) >= abs (max), set VR to [-min, min].  */
623e4b17023SJohn Marino 
624e4b17023SJohn Marino static void
abs_extent_range(value_range_t * vr,tree min,tree max)625e4b17023SJohn Marino abs_extent_range (value_range_t *vr, tree min, tree max)
626e4b17023SJohn Marino {
627e4b17023SJohn Marino   int cmp;
628e4b17023SJohn Marino 
629e4b17023SJohn Marino   gcc_assert (TREE_CODE (min) == INTEGER_CST);
630e4b17023SJohn Marino   gcc_assert (TREE_CODE (max) == INTEGER_CST);
631e4b17023SJohn Marino   gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (min)));
632e4b17023SJohn Marino   gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (min)));
633e4b17023SJohn Marino   min = fold_unary (ABS_EXPR, TREE_TYPE (min), min);
634e4b17023SJohn Marino   max = fold_unary (ABS_EXPR, TREE_TYPE (max), max);
635e4b17023SJohn Marino   if (TREE_OVERFLOW (min) || TREE_OVERFLOW (max))
636e4b17023SJohn Marino     {
637e4b17023SJohn Marino       set_value_range_to_varying (vr);
638e4b17023SJohn Marino       return;
639e4b17023SJohn Marino     }
640e4b17023SJohn Marino   cmp = compare_values (min, max);
641e4b17023SJohn Marino   if (cmp == -1)
642e4b17023SJohn Marino     min = fold_unary (NEGATE_EXPR, TREE_TYPE (min), max);
643e4b17023SJohn Marino   else if (cmp == 0 || cmp == 1)
644e4b17023SJohn Marino     {
645e4b17023SJohn Marino       max = min;
646e4b17023SJohn Marino       min = fold_unary (NEGATE_EXPR, TREE_TYPE (min), min);
647e4b17023SJohn Marino     }
648e4b17023SJohn Marino   else
649e4b17023SJohn Marino     {
650e4b17023SJohn Marino       set_value_range_to_varying (vr);
651e4b17023SJohn Marino       return;
652e4b17023SJohn Marino     }
653e4b17023SJohn Marino   set_and_canonicalize_value_range (vr, VR_RANGE, min, max, NULL);
654e4b17023SJohn Marino }
655e4b17023SJohn Marino 
656e4b17023SJohn Marino 
657e4b17023SJohn Marino /* Return value range information for VAR.
658e4b17023SJohn Marino 
659e4b17023SJohn Marino    If we have no values ranges recorded (ie, VRP is not running), then
660e4b17023SJohn Marino    return NULL.  Otherwise create an empty range if none existed for VAR.  */
661e4b17023SJohn Marino 
662e4b17023SJohn Marino static value_range_t *
get_value_range(const_tree var)663e4b17023SJohn Marino get_value_range (const_tree var)
664e4b17023SJohn Marino {
665e4b17023SJohn Marino   static const struct value_range_d vr_const_varying
666e4b17023SJohn Marino     = { VR_VARYING, NULL_TREE, NULL_TREE, NULL };
667e4b17023SJohn Marino   value_range_t *vr;
668e4b17023SJohn Marino   tree sym;
669e4b17023SJohn Marino   unsigned ver = SSA_NAME_VERSION (var);
670e4b17023SJohn Marino 
671e4b17023SJohn Marino   /* If we have no recorded ranges, then return NULL.  */
672e4b17023SJohn Marino   if (! vr_value)
673e4b17023SJohn Marino     return NULL;
674e4b17023SJohn Marino 
675e4b17023SJohn Marino   /* If we query the range for a new SSA name return an unmodifiable VARYING.
676e4b17023SJohn Marino      We should get here at most from the substitute-and-fold stage which
677e4b17023SJohn Marino      will never try to change values.  */
678e4b17023SJohn Marino   if (ver >= num_vr_values)
679e4b17023SJohn Marino     return CONST_CAST (value_range_t *, &vr_const_varying);
680e4b17023SJohn Marino 
681e4b17023SJohn Marino   vr = vr_value[ver];
682e4b17023SJohn Marino   if (vr)
683e4b17023SJohn Marino     return vr;
684e4b17023SJohn Marino 
685e4b17023SJohn Marino   /* After propagation finished do not allocate new value-ranges.  */
686e4b17023SJohn Marino   if (values_propagated)
687e4b17023SJohn Marino     return CONST_CAST (value_range_t *, &vr_const_varying);
688e4b17023SJohn Marino 
689e4b17023SJohn Marino   /* Create a default value range.  */
690e4b17023SJohn Marino   vr_value[ver] = vr = XCNEW (value_range_t);
691e4b17023SJohn Marino 
692e4b17023SJohn Marino   /* Defer allocating the equivalence set.  */
693e4b17023SJohn Marino   vr->equiv = NULL;
694e4b17023SJohn Marino 
695e4b17023SJohn Marino   /* If VAR is a default definition of a parameter, the variable can
696e4b17023SJohn Marino      take any value in VAR's type.  */
697e4b17023SJohn Marino   sym = SSA_NAME_VAR (var);
698e4b17023SJohn Marino   if (SSA_NAME_IS_DEFAULT_DEF (var))
699e4b17023SJohn Marino     {
700e4b17023SJohn Marino       if (TREE_CODE (sym) == PARM_DECL)
701e4b17023SJohn Marino 	{
702e4b17023SJohn Marino 	  /* Try to use the "nonnull" attribute to create ~[0, 0]
703e4b17023SJohn Marino 	     anti-ranges for pointers.  Note that this is only valid with
704e4b17023SJohn Marino 	     default definitions of PARM_DECLs.  */
705e4b17023SJohn Marino 	  if (POINTER_TYPE_P (TREE_TYPE (sym))
706e4b17023SJohn Marino 	      && nonnull_arg_p (sym))
707e4b17023SJohn Marino 	    set_value_range_to_nonnull (vr, TREE_TYPE (sym));
708e4b17023SJohn Marino 	  else
709e4b17023SJohn Marino 	    set_value_range_to_varying (vr);
710e4b17023SJohn Marino 	}
711e4b17023SJohn Marino       else if (TREE_CODE (sym) == RESULT_DECL
712e4b17023SJohn Marino 	       && DECL_BY_REFERENCE (sym))
713e4b17023SJohn Marino 	set_value_range_to_nonnull (vr, TREE_TYPE (sym));
714e4b17023SJohn Marino     }
715e4b17023SJohn Marino 
716e4b17023SJohn Marino   return vr;
717e4b17023SJohn Marino }
718e4b17023SJohn Marino 
719e4b17023SJohn Marino /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
720e4b17023SJohn Marino 
721e4b17023SJohn Marino static inline bool
vrp_operand_equal_p(const_tree val1,const_tree val2)722e4b17023SJohn Marino vrp_operand_equal_p (const_tree val1, const_tree val2)
723e4b17023SJohn Marino {
724e4b17023SJohn Marino   if (val1 == val2)
725e4b17023SJohn Marino     return true;
726e4b17023SJohn Marino   if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
727e4b17023SJohn Marino     return false;
728e4b17023SJohn Marino   if (is_overflow_infinity (val1))
729e4b17023SJohn Marino     return is_overflow_infinity (val2);
730e4b17023SJohn Marino   return true;
731e4b17023SJohn Marino }
732e4b17023SJohn Marino 
733e4b17023SJohn Marino /* Return true, if the bitmaps B1 and B2 are equal.  */
734e4b17023SJohn Marino 
735e4b17023SJohn Marino static inline bool
vrp_bitmap_equal_p(const_bitmap b1,const_bitmap b2)736e4b17023SJohn Marino vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
737e4b17023SJohn Marino {
738e4b17023SJohn Marino   return (b1 == b2
739e4b17023SJohn Marino 	  || ((!b1 || bitmap_empty_p (b1))
740e4b17023SJohn Marino 	      && (!b2 || bitmap_empty_p (b2)))
741e4b17023SJohn Marino 	  || (b1 && b2
742e4b17023SJohn Marino 	      && bitmap_equal_p (b1, b2)));
743e4b17023SJohn Marino }
744e4b17023SJohn Marino 
745e4b17023SJohn Marino /* Update the value range and equivalence set for variable VAR to
746e4b17023SJohn Marino    NEW_VR.  Return true if NEW_VR is different from VAR's previous
747e4b17023SJohn Marino    value.
748e4b17023SJohn Marino 
749e4b17023SJohn Marino    NOTE: This function assumes that NEW_VR is a temporary value range
750e4b17023SJohn Marino    object created for the sole purpose of updating VAR's range.  The
751e4b17023SJohn Marino    storage used by the equivalence set from NEW_VR will be freed by
752e4b17023SJohn Marino    this function.  Do not call update_value_range when NEW_VR
753e4b17023SJohn Marino    is the range object associated with another SSA name.  */
754e4b17023SJohn Marino 
755e4b17023SJohn Marino static inline bool
update_value_range(const_tree var,value_range_t * new_vr)756e4b17023SJohn Marino update_value_range (const_tree var, value_range_t *new_vr)
757e4b17023SJohn Marino {
758e4b17023SJohn Marino   value_range_t *old_vr;
759e4b17023SJohn Marino   bool is_new;
760e4b17023SJohn Marino 
761e4b17023SJohn Marino   /* Update the value range, if necessary.  */
762e4b17023SJohn Marino   old_vr = get_value_range (var);
763e4b17023SJohn Marino   is_new = old_vr->type != new_vr->type
764e4b17023SJohn Marino 	   || !vrp_operand_equal_p (old_vr->min, new_vr->min)
765e4b17023SJohn Marino 	   || !vrp_operand_equal_p (old_vr->max, new_vr->max)
766e4b17023SJohn Marino 	   || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
767e4b17023SJohn Marino 
768e4b17023SJohn Marino   if (is_new)
769e4b17023SJohn Marino     set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
770e4b17023SJohn Marino 	             new_vr->equiv);
771e4b17023SJohn Marino 
772e4b17023SJohn Marino   BITMAP_FREE (new_vr->equiv);
773e4b17023SJohn Marino 
774e4b17023SJohn Marino   return is_new;
775e4b17023SJohn Marino }
776e4b17023SJohn Marino 
777e4b17023SJohn Marino 
778e4b17023SJohn Marino /* Add VAR and VAR's equivalence set to EQUIV.  This is the central
779e4b17023SJohn Marino    point where equivalence processing can be turned on/off.  */
780e4b17023SJohn Marino 
781e4b17023SJohn Marino static void
add_equivalence(bitmap * equiv,const_tree var)782e4b17023SJohn Marino add_equivalence (bitmap *equiv, const_tree var)
783e4b17023SJohn Marino {
784e4b17023SJohn Marino   unsigned ver = SSA_NAME_VERSION (var);
785e4b17023SJohn Marino   value_range_t *vr = vr_value[ver];
786e4b17023SJohn Marino 
787e4b17023SJohn Marino   if (*equiv == NULL)
788e4b17023SJohn Marino     *equiv = BITMAP_ALLOC (NULL);
789e4b17023SJohn Marino   bitmap_set_bit (*equiv, ver);
790e4b17023SJohn Marino   if (vr && vr->equiv)
791e4b17023SJohn Marino     bitmap_ior_into (*equiv, vr->equiv);
792e4b17023SJohn Marino }
793e4b17023SJohn Marino 
794e4b17023SJohn Marino 
795e4b17023SJohn Marino /* Return true if VR is ~[0, 0].  */
796e4b17023SJohn Marino 
797e4b17023SJohn Marino static inline bool
range_is_nonnull(value_range_t * vr)798e4b17023SJohn Marino range_is_nonnull (value_range_t *vr)
799e4b17023SJohn Marino {
800e4b17023SJohn Marino   return vr->type == VR_ANTI_RANGE
801e4b17023SJohn Marino 	 && integer_zerop (vr->min)
802e4b17023SJohn Marino 	 && integer_zerop (vr->max);
803e4b17023SJohn Marino }
804e4b17023SJohn Marino 
805e4b17023SJohn Marino 
806e4b17023SJohn Marino /* Return true if VR is [0, 0].  */
807e4b17023SJohn Marino 
808e4b17023SJohn Marino static inline bool
range_is_null(value_range_t * vr)809e4b17023SJohn Marino range_is_null (value_range_t *vr)
810e4b17023SJohn Marino {
811e4b17023SJohn Marino   return vr->type == VR_RANGE
812e4b17023SJohn Marino 	 && integer_zerop (vr->min)
813e4b17023SJohn Marino 	 && integer_zerop (vr->max);
814e4b17023SJohn Marino }
815e4b17023SJohn Marino 
816e4b17023SJohn Marino /* Return true if max and min of VR are INTEGER_CST.  It's not necessary
817e4b17023SJohn Marino    a singleton.  */
818e4b17023SJohn Marino 
819e4b17023SJohn Marino static inline bool
range_int_cst_p(value_range_t * vr)820e4b17023SJohn Marino range_int_cst_p (value_range_t *vr)
821e4b17023SJohn Marino {
822e4b17023SJohn Marino   return (vr->type == VR_RANGE
823e4b17023SJohn Marino 	  && TREE_CODE (vr->max) == INTEGER_CST
824e4b17023SJohn Marino 	  && TREE_CODE (vr->min) == INTEGER_CST
825e4b17023SJohn Marino 	  && !TREE_OVERFLOW (vr->max)
826e4b17023SJohn Marino 	  && !TREE_OVERFLOW (vr->min));
827e4b17023SJohn Marino }
828e4b17023SJohn Marino 
829e4b17023SJohn Marino /* Return true if VR is a INTEGER_CST singleton.  */
830e4b17023SJohn Marino 
831e4b17023SJohn Marino static inline bool
range_int_cst_singleton_p(value_range_t * vr)832e4b17023SJohn Marino range_int_cst_singleton_p (value_range_t *vr)
833e4b17023SJohn Marino {
834e4b17023SJohn Marino   return (range_int_cst_p (vr)
835e4b17023SJohn Marino 	  && tree_int_cst_equal (vr->min, vr->max));
836e4b17023SJohn Marino }
837e4b17023SJohn Marino 
838e4b17023SJohn Marino /* Return true if value range VR involves at least one symbol.  */
839e4b17023SJohn Marino 
840e4b17023SJohn Marino static inline bool
symbolic_range_p(value_range_t * vr)841e4b17023SJohn Marino symbolic_range_p (value_range_t *vr)
842e4b17023SJohn Marino {
843e4b17023SJohn Marino   return (!is_gimple_min_invariant (vr->min)
844e4b17023SJohn Marino           || !is_gimple_min_invariant (vr->max));
845e4b17023SJohn Marino }
846e4b17023SJohn Marino 
847e4b17023SJohn Marino /* Return true if value range VR uses an overflow infinity.  */
848e4b17023SJohn Marino 
849e4b17023SJohn Marino static inline bool
overflow_infinity_range_p(value_range_t * vr)850e4b17023SJohn Marino overflow_infinity_range_p (value_range_t *vr)
851e4b17023SJohn Marino {
852e4b17023SJohn Marino   return (vr->type == VR_RANGE
853e4b17023SJohn Marino 	  && (is_overflow_infinity (vr->min)
854e4b17023SJohn Marino 	      || is_overflow_infinity (vr->max)));
855e4b17023SJohn Marino }
856e4b17023SJohn Marino 
857e4b17023SJohn Marino /* Return false if we can not make a valid comparison based on VR;
858e4b17023SJohn Marino    this will be the case if it uses an overflow infinity and overflow
859e4b17023SJohn Marino    is not undefined (i.e., -fno-strict-overflow is in effect).
860e4b17023SJohn Marino    Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
861e4b17023SJohn Marino    uses an overflow infinity.  */
862e4b17023SJohn Marino 
863e4b17023SJohn Marino static bool
usable_range_p(value_range_t * vr,bool * strict_overflow_p)864e4b17023SJohn Marino usable_range_p (value_range_t *vr, bool *strict_overflow_p)
865e4b17023SJohn Marino {
866e4b17023SJohn Marino   gcc_assert (vr->type == VR_RANGE);
867e4b17023SJohn Marino   if (is_overflow_infinity (vr->min))
868e4b17023SJohn Marino     {
869e4b17023SJohn Marino       *strict_overflow_p = true;
870e4b17023SJohn Marino       if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
871e4b17023SJohn Marino 	return false;
872e4b17023SJohn Marino     }
873e4b17023SJohn Marino   if (is_overflow_infinity (vr->max))
874e4b17023SJohn Marino     {
875e4b17023SJohn Marino       *strict_overflow_p = true;
876e4b17023SJohn Marino       if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
877e4b17023SJohn Marino 	return false;
878e4b17023SJohn Marino     }
879e4b17023SJohn Marino   return true;
880e4b17023SJohn Marino }
881e4b17023SJohn Marino 
882e4b17023SJohn Marino 
883e4b17023SJohn Marino /* Return true if the result of assignment STMT is know to be non-negative.
884e4b17023SJohn Marino    If the return value is based on the assumption that signed overflow is
885e4b17023SJohn Marino    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
886e4b17023SJohn Marino    *STRICT_OVERFLOW_P.*/
887e4b17023SJohn Marino 
888e4b17023SJohn Marino static bool
gimple_assign_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)889e4b17023SJohn Marino gimple_assign_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
890e4b17023SJohn Marino {
891e4b17023SJohn Marino   enum tree_code code = gimple_assign_rhs_code (stmt);
892e4b17023SJohn Marino   switch (get_gimple_rhs_class (code))
893e4b17023SJohn Marino     {
894e4b17023SJohn Marino     case GIMPLE_UNARY_RHS:
895e4b17023SJohn Marino       return tree_unary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
896e4b17023SJohn Marino 					     gimple_expr_type (stmt),
897e4b17023SJohn Marino 					     gimple_assign_rhs1 (stmt),
898e4b17023SJohn Marino 					     strict_overflow_p);
899e4b17023SJohn Marino     case GIMPLE_BINARY_RHS:
900e4b17023SJohn Marino       return tree_binary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
901e4b17023SJohn Marino 					      gimple_expr_type (stmt),
902e4b17023SJohn Marino 					      gimple_assign_rhs1 (stmt),
903e4b17023SJohn Marino 					      gimple_assign_rhs2 (stmt),
904e4b17023SJohn Marino 					      strict_overflow_p);
905e4b17023SJohn Marino     case GIMPLE_TERNARY_RHS:
906e4b17023SJohn Marino       return false;
907e4b17023SJohn Marino     case GIMPLE_SINGLE_RHS:
908e4b17023SJohn Marino       return tree_single_nonnegative_warnv_p (gimple_assign_rhs1 (stmt),
909e4b17023SJohn Marino 					      strict_overflow_p);
910e4b17023SJohn Marino     case GIMPLE_INVALID_RHS:
911e4b17023SJohn Marino       gcc_unreachable ();
912e4b17023SJohn Marino     default:
913e4b17023SJohn Marino       gcc_unreachable ();
914e4b17023SJohn Marino     }
915e4b17023SJohn Marino }
916e4b17023SJohn Marino 
917e4b17023SJohn Marino /* Return true if return value of call STMT is know to be non-negative.
918e4b17023SJohn Marino    If the return value is based on the assumption that signed overflow is
919e4b17023SJohn Marino    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
920e4b17023SJohn Marino    *STRICT_OVERFLOW_P.*/
921e4b17023SJohn Marino 
922e4b17023SJohn Marino static bool
gimple_call_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)923e4b17023SJohn Marino gimple_call_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
924e4b17023SJohn Marino {
925e4b17023SJohn Marino   tree arg0 = gimple_call_num_args (stmt) > 0 ?
926e4b17023SJohn Marino     gimple_call_arg (stmt, 0) : NULL_TREE;
927e4b17023SJohn Marino   tree arg1 = gimple_call_num_args (stmt) > 1 ?
928e4b17023SJohn Marino     gimple_call_arg (stmt, 1) : NULL_TREE;
929e4b17023SJohn Marino 
930e4b17023SJohn Marino   return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt),
931e4b17023SJohn Marino 					gimple_call_fndecl (stmt),
932e4b17023SJohn Marino 					arg0,
933e4b17023SJohn Marino 					arg1,
934e4b17023SJohn Marino 					strict_overflow_p);
935e4b17023SJohn Marino }
936e4b17023SJohn Marino 
937e4b17023SJohn Marino /* Return true if STMT is know to to compute a non-negative value.
938e4b17023SJohn Marino    If the return value is based on the assumption that signed overflow is
939e4b17023SJohn Marino    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
940e4b17023SJohn Marino    *STRICT_OVERFLOW_P.*/
941e4b17023SJohn Marino 
942e4b17023SJohn Marino static bool
gimple_stmt_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)943e4b17023SJohn Marino gimple_stmt_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
944e4b17023SJohn Marino {
945e4b17023SJohn Marino   switch (gimple_code (stmt))
946e4b17023SJohn Marino     {
947e4b17023SJohn Marino     case GIMPLE_ASSIGN:
948e4b17023SJohn Marino       return gimple_assign_nonnegative_warnv_p (stmt, strict_overflow_p);
949e4b17023SJohn Marino     case GIMPLE_CALL:
950e4b17023SJohn Marino       return gimple_call_nonnegative_warnv_p (stmt, strict_overflow_p);
951e4b17023SJohn Marino     default:
952e4b17023SJohn Marino       gcc_unreachable ();
953e4b17023SJohn Marino     }
954e4b17023SJohn Marino }
955e4b17023SJohn Marino 
956e4b17023SJohn Marino /* Return true if the result of assignment STMT is know to be non-zero.
957e4b17023SJohn Marino    If the return value is based on the assumption that signed overflow is
958e4b17023SJohn Marino    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
959e4b17023SJohn Marino    *STRICT_OVERFLOW_P.*/
960e4b17023SJohn Marino 
961e4b17023SJohn Marino static bool
gimple_assign_nonzero_warnv_p(gimple stmt,bool * strict_overflow_p)962e4b17023SJohn Marino gimple_assign_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
963e4b17023SJohn Marino {
964e4b17023SJohn Marino   enum tree_code code = gimple_assign_rhs_code (stmt);
965e4b17023SJohn Marino   switch (get_gimple_rhs_class (code))
966e4b17023SJohn Marino     {
967e4b17023SJohn Marino     case GIMPLE_UNARY_RHS:
968e4b17023SJohn Marino       return tree_unary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
969e4b17023SJohn Marino 					 gimple_expr_type (stmt),
970e4b17023SJohn Marino 					 gimple_assign_rhs1 (stmt),
971e4b17023SJohn Marino 					 strict_overflow_p);
972e4b17023SJohn Marino     case GIMPLE_BINARY_RHS:
973e4b17023SJohn Marino       return tree_binary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
974e4b17023SJohn Marino 					  gimple_expr_type (stmt),
975e4b17023SJohn Marino 					  gimple_assign_rhs1 (stmt),
976e4b17023SJohn Marino 					  gimple_assign_rhs2 (stmt),
977e4b17023SJohn Marino 					  strict_overflow_p);
978e4b17023SJohn Marino     case GIMPLE_TERNARY_RHS:
979e4b17023SJohn Marino       return false;
980e4b17023SJohn Marino     case GIMPLE_SINGLE_RHS:
981e4b17023SJohn Marino       return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
982e4b17023SJohn Marino 					  strict_overflow_p);
983e4b17023SJohn Marino     case GIMPLE_INVALID_RHS:
984e4b17023SJohn Marino       gcc_unreachable ();
985e4b17023SJohn Marino     default:
986e4b17023SJohn Marino       gcc_unreachable ();
987e4b17023SJohn Marino     }
988e4b17023SJohn Marino }
989e4b17023SJohn Marino 
990e4b17023SJohn Marino /* Return true if STMT is know to to compute a non-zero value.
991e4b17023SJohn Marino    If the return value is based on the assumption that signed overflow is
992e4b17023SJohn Marino    undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
993e4b17023SJohn Marino    *STRICT_OVERFLOW_P.*/
994e4b17023SJohn Marino 
995e4b17023SJohn Marino static bool
gimple_stmt_nonzero_warnv_p(gimple stmt,bool * strict_overflow_p)996e4b17023SJohn Marino gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
997e4b17023SJohn Marino {
998e4b17023SJohn Marino   switch (gimple_code (stmt))
999e4b17023SJohn Marino     {
1000e4b17023SJohn Marino     case GIMPLE_ASSIGN:
1001e4b17023SJohn Marino       return gimple_assign_nonzero_warnv_p (stmt, strict_overflow_p);
1002e4b17023SJohn Marino     case GIMPLE_CALL:
1003e4b17023SJohn Marino       return gimple_alloca_call_p (stmt);
1004e4b17023SJohn Marino     default:
1005e4b17023SJohn Marino       gcc_unreachable ();
1006e4b17023SJohn Marino     }
1007e4b17023SJohn Marino }
1008e4b17023SJohn Marino 
1009e4b17023SJohn Marino /* Like tree_expr_nonzero_warnv_p, but this function uses value ranges
1010e4b17023SJohn Marino    obtained so far.  */
1011e4b17023SJohn Marino 
1012e4b17023SJohn Marino static bool
vrp_stmt_computes_nonzero(gimple stmt,bool * strict_overflow_p)1013e4b17023SJohn Marino vrp_stmt_computes_nonzero (gimple stmt, bool *strict_overflow_p)
1014e4b17023SJohn Marino {
1015e4b17023SJohn Marino   if (gimple_stmt_nonzero_warnv_p (stmt, strict_overflow_p))
1016e4b17023SJohn Marino     return true;
1017e4b17023SJohn Marino 
1018e4b17023SJohn Marino   /* If we have an expression of the form &X->a, then the expression
1019e4b17023SJohn Marino      is nonnull if X is nonnull.  */
1020e4b17023SJohn Marino   if (is_gimple_assign (stmt)
1021e4b17023SJohn Marino       && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
1022e4b17023SJohn Marino     {
1023e4b17023SJohn Marino       tree expr = gimple_assign_rhs1 (stmt);
1024e4b17023SJohn Marino       tree base = get_base_address (TREE_OPERAND (expr, 0));
1025e4b17023SJohn Marino 
1026e4b17023SJohn Marino       if (base != NULL_TREE
1027e4b17023SJohn Marino 	  && TREE_CODE (base) == MEM_REF
1028e4b17023SJohn Marino 	  && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1029e4b17023SJohn Marino 	{
1030e4b17023SJohn Marino 	  value_range_t *vr = get_value_range (TREE_OPERAND (base, 0));
1031e4b17023SJohn Marino 	  if (range_is_nonnull (vr))
1032e4b17023SJohn Marino 	    return true;
1033e4b17023SJohn Marino 	}
1034e4b17023SJohn Marino     }
1035e4b17023SJohn Marino 
1036e4b17023SJohn Marino   return false;
1037e4b17023SJohn Marino }
1038e4b17023SJohn Marino 
1039e4b17023SJohn Marino /* Returns true if EXPR is a valid value (as expected by compare_values) --
1040e4b17023SJohn Marino    a gimple invariant, or SSA_NAME +- CST.  */
1041e4b17023SJohn Marino 
1042e4b17023SJohn Marino static bool
valid_value_p(tree expr)1043e4b17023SJohn Marino valid_value_p (tree expr)
1044e4b17023SJohn Marino {
1045e4b17023SJohn Marino   if (TREE_CODE (expr) == SSA_NAME)
1046e4b17023SJohn Marino     return true;
1047e4b17023SJohn Marino 
1048e4b17023SJohn Marino   if (TREE_CODE (expr) == PLUS_EXPR
1049e4b17023SJohn Marino       || TREE_CODE (expr) == MINUS_EXPR)
1050e4b17023SJohn Marino     return (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
1051e4b17023SJohn Marino 	    && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST);
1052e4b17023SJohn Marino 
1053e4b17023SJohn Marino   return is_gimple_min_invariant (expr);
1054e4b17023SJohn Marino }
1055e4b17023SJohn Marino 
1056e4b17023SJohn Marino /* Return
1057e4b17023SJohn Marino    1 if VAL < VAL2
1058e4b17023SJohn Marino    0 if !(VAL < VAL2)
1059e4b17023SJohn Marino    -2 if those are incomparable.  */
1060e4b17023SJohn Marino static inline int
operand_less_p(tree val,tree val2)1061e4b17023SJohn Marino operand_less_p (tree val, tree val2)
1062e4b17023SJohn Marino {
1063e4b17023SJohn Marino   /* LT is folded faster than GE and others.  Inline the common case.  */
1064e4b17023SJohn Marino   if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
1065e4b17023SJohn Marino     {
1066e4b17023SJohn Marino       if (TYPE_UNSIGNED (TREE_TYPE (val)))
1067e4b17023SJohn Marino 	return INT_CST_LT_UNSIGNED (val, val2);
1068e4b17023SJohn Marino       else
1069e4b17023SJohn Marino 	{
1070e4b17023SJohn Marino 	  if (INT_CST_LT (val, val2))
1071e4b17023SJohn Marino 	    return 1;
1072e4b17023SJohn Marino 	}
1073e4b17023SJohn Marino     }
1074e4b17023SJohn Marino   else
1075e4b17023SJohn Marino     {
1076e4b17023SJohn Marino       tree tcmp;
1077e4b17023SJohn Marino 
1078e4b17023SJohn Marino       fold_defer_overflow_warnings ();
1079e4b17023SJohn Marino 
1080e4b17023SJohn Marino       tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);
1081e4b17023SJohn Marino 
1082e4b17023SJohn Marino       fold_undefer_and_ignore_overflow_warnings ();
1083e4b17023SJohn Marino 
1084e4b17023SJohn Marino       if (!tcmp
1085e4b17023SJohn Marino 	  || TREE_CODE (tcmp) != INTEGER_CST)
1086e4b17023SJohn Marino 	return -2;
1087e4b17023SJohn Marino 
1088e4b17023SJohn Marino       if (!integer_zerop (tcmp))
1089e4b17023SJohn Marino 	return 1;
1090e4b17023SJohn Marino     }
1091e4b17023SJohn Marino 
1092e4b17023SJohn Marino   /* val >= val2, not considering overflow infinity.  */
1093e4b17023SJohn Marino   if (is_negative_overflow_infinity (val))
1094e4b17023SJohn Marino     return is_negative_overflow_infinity (val2) ? 0 : 1;
1095e4b17023SJohn Marino   else if (is_positive_overflow_infinity (val2))
1096e4b17023SJohn Marino     return is_positive_overflow_infinity (val) ? 0 : 1;
1097e4b17023SJohn Marino 
1098e4b17023SJohn Marino   return 0;
1099e4b17023SJohn Marino }
1100e4b17023SJohn Marino 
1101e4b17023SJohn Marino /* Compare two values VAL1 and VAL2.  Return
1102e4b17023SJohn Marino 
1103e4b17023SJohn Marino    	-2 if VAL1 and VAL2 cannot be compared at compile-time,
1104e4b17023SJohn Marino    	-1 if VAL1 < VAL2,
1105e4b17023SJohn Marino    	 0 if VAL1 == VAL2,
1106e4b17023SJohn Marino 	+1 if VAL1 > VAL2, and
1107e4b17023SJohn Marino 	+2 if VAL1 != VAL2
1108e4b17023SJohn Marino 
1109e4b17023SJohn Marino    This is similar to tree_int_cst_compare but supports pointer values
1110e4b17023SJohn Marino    and values that cannot be compared at compile time.
1111e4b17023SJohn Marino 
1112e4b17023SJohn Marino    If STRICT_OVERFLOW_P is not NULL, then set *STRICT_OVERFLOW_P to
1113e4b17023SJohn Marino    true if the return value is only valid if we assume that signed
1114e4b17023SJohn Marino    overflow is undefined.  */
1115e4b17023SJohn Marino 
1116e4b17023SJohn Marino static int
compare_values_warnv(tree val1,tree val2,bool * strict_overflow_p)1117e4b17023SJohn Marino compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
1118e4b17023SJohn Marino {
1119e4b17023SJohn Marino   if (val1 == val2)
1120e4b17023SJohn Marino     return 0;
1121e4b17023SJohn Marino 
1122e4b17023SJohn Marino   /* Below we rely on the fact that VAL1 and VAL2 are both pointers or
1123e4b17023SJohn Marino      both integers.  */
1124e4b17023SJohn Marino   gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
1125e4b17023SJohn Marino 	      == POINTER_TYPE_P (TREE_TYPE (val2)));
1126e4b17023SJohn Marino   /* Convert the two values into the same type.  This is needed because
1127e4b17023SJohn Marino      sizetype causes sign extension even for unsigned types.  */
1128e4b17023SJohn Marino   val2 = fold_convert (TREE_TYPE (val1), val2);
1129e4b17023SJohn Marino   STRIP_USELESS_TYPE_CONVERSION (val2);
1130e4b17023SJohn Marino 
1131e4b17023SJohn Marino   if ((TREE_CODE (val1) == SSA_NAME
1132e4b17023SJohn Marino        || TREE_CODE (val1) == PLUS_EXPR
1133e4b17023SJohn Marino        || TREE_CODE (val1) == MINUS_EXPR)
1134e4b17023SJohn Marino       && (TREE_CODE (val2) == SSA_NAME
1135e4b17023SJohn Marino 	  || TREE_CODE (val2) == PLUS_EXPR
1136e4b17023SJohn Marino 	  || TREE_CODE (val2) == MINUS_EXPR))
1137e4b17023SJohn Marino     {
1138e4b17023SJohn Marino       tree n1, c1, n2, c2;
1139e4b17023SJohn Marino       enum tree_code code1, code2;
1140e4b17023SJohn Marino 
1141e4b17023SJohn Marino       /* If VAL1 and VAL2 are of the form 'NAME [+-] CST' or 'NAME',
1142e4b17023SJohn Marino 	 return -1 or +1 accordingly.  If VAL1 and VAL2 don't use the
1143e4b17023SJohn Marino 	 same name, return -2.  */
1144e4b17023SJohn Marino       if (TREE_CODE (val1) == SSA_NAME)
1145e4b17023SJohn Marino 	{
1146e4b17023SJohn Marino 	  code1 = SSA_NAME;
1147e4b17023SJohn Marino 	  n1 = val1;
1148e4b17023SJohn Marino 	  c1 = NULL_TREE;
1149e4b17023SJohn Marino 	}
1150e4b17023SJohn Marino       else
1151e4b17023SJohn Marino 	{
1152e4b17023SJohn Marino 	  code1 = TREE_CODE (val1);
1153e4b17023SJohn Marino 	  n1 = TREE_OPERAND (val1, 0);
1154e4b17023SJohn Marino 	  c1 = TREE_OPERAND (val1, 1);
1155e4b17023SJohn Marino 	  if (tree_int_cst_sgn (c1) == -1)
1156e4b17023SJohn Marino 	    {
1157e4b17023SJohn Marino 	      if (is_negative_overflow_infinity (c1))
1158e4b17023SJohn Marino 		return -2;
1159e4b17023SJohn Marino 	      c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
1160e4b17023SJohn Marino 	      if (!c1)
1161e4b17023SJohn Marino 		return -2;
1162e4b17023SJohn Marino 	      code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
1163e4b17023SJohn Marino 	    }
1164e4b17023SJohn Marino 	}
1165e4b17023SJohn Marino 
1166e4b17023SJohn Marino       if (TREE_CODE (val2) == SSA_NAME)
1167e4b17023SJohn Marino 	{
1168e4b17023SJohn Marino 	  code2 = SSA_NAME;
1169e4b17023SJohn Marino 	  n2 = val2;
1170e4b17023SJohn Marino 	  c2 = NULL_TREE;
1171e4b17023SJohn Marino 	}
1172e4b17023SJohn Marino       else
1173e4b17023SJohn Marino 	{
1174e4b17023SJohn Marino 	  code2 = TREE_CODE (val2);
1175e4b17023SJohn Marino 	  n2 = TREE_OPERAND (val2, 0);
1176e4b17023SJohn Marino 	  c2 = TREE_OPERAND (val2, 1);
1177e4b17023SJohn Marino 	  if (tree_int_cst_sgn (c2) == -1)
1178e4b17023SJohn Marino 	    {
1179e4b17023SJohn Marino 	      if (is_negative_overflow_infinity (c2))
1180e4b17023SJohn Marino 		return -2;
1181e4b17023SJohn Marino 	      c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
1182e4b17023SJohn Marino 	      if (!c2)
1183e4b17023SJohn Marino 		return -2;
1184e4b17023SJohn Marino 	      code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
1185e4b17023SJohn Marino 	    }
1186e4b17023SJohn Marino 	}
1187e4b17023SJohn Marino 
1188e4b17023SJohn Marino       /* Both values must use the same name.  */
1189e4b17023SJohn Marino       if (n1 != n2)
1190e4b17023SJohn Marino 	return -2;
1191e4b17023SJohn Marino 
1192e4b17023SJohn Marino       if (code1 == SSA_NAME
1193e4b17023SJohn Marino 	  && code2 == SSA_NAME)
1194e4b17023SJohn Marino 	/* NAME == NAME  */
1195e4b17023SJohn Marino 	return 0;
1196e4b17023SJohn Marino 
1197e4b17023SJohn Marino       /* If overflow is defined we cannot simplify more.  */
1198e4b17023SJohn Marino       if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
1199e4b17023SJohn Marino 	return -2;
1200e4b17023SJohn Marino 
1201e4b17023SJohn Marino       if (strict_overflow_p != NULL
1202e4b17023SJohn Marino 	  && (code1 == SSA_NAME || !TREE_NO_WARNING (val1))
1203e4b17023SJohn Marino 	  && (code2 == SSA_NAME || !TREE_NO_WARNING (val2)))
1204e4b17023SJohn Marino 	*strict_overflow_p = true;
1205e4b17023SJohn Marino 
1206e4b17023SJohn Marino       if (code1 == SSA_NAME)
1207e4b17023SJohn Marino 	{
1208e4b17023SJohn Marino 	  if (code2 == PLUS_EXPR)
1209e4b17023SJohn Marino 	    /* NAME < NAME + CST  */
1210e4b17023SJohn Marino 	    return -1;
1211e4b17023SJohn Marino 	  else if (code2 == MINUS_EXPR)
1212e4b17023SJohn Marino 	    /* NAME > NAME - CST  */
1213e4b17023SJohn Marino 	    return 1;
1214e4b17023SJohn Marino 	}
1215e4b17023SJohn Marino       else if (code1 == PLUS_EXPR)
1216e4b17023SJohn Marino 	{
1217e4b17023SJohn Marino 	  if (code2 == SSA_NAME)
1218e4b17023SJohn Marino 	    /* NAME + CST > NAME  */
1219e4b17023SJohn Marino 	    return 1;
1220e4b17023SJohn Marino 	  else if (code2 == PLUS_EXPR)
1221e4b17023SJohn Marino 	    /* NAME + CST1 > NAME + CST2, if CST1 > CST2  */
1222e4b17023SJohn Marino 	    return compare_values_warnv (c1, c2, strict_overflow_p);
1223e4b17023SJohn Marino 	  else if (code2 == MINUS_EXPR)
1224e4b17023SJohn Marino 	    /* NAME + CST1 > NAME - CST2  */
1225e4b17023SJohn Marino 	    return 1;
1226e4b17023SJohn Marino 	}
1227e4b17023SJohn Marino       else if (code1 == MINUS_EXPR)
1228e4b17023SJohn Marino 	{
1229e4b17023SJohn Marino 	  if (code2 == SSA_NAME)
1230e4b17023SJohn Marino 	    /* NAME - CST < NAME  */
1231e4b17023SJohn Marino 	    return -1;
1232e4b17023SJohn Marino 	  else if (code2 == PLUS_EXPR)
1233e4b17023SJohn Marino 	    /* NAME - CST1 < NAME + CST2  */
1234e4b17023SJohn Marino 	    return -1;
1235e4b17023SJohn Marino 	  else if (code2 == MINUS_EXPR)
1236e4b17023SJohn Marino 	    /* NAME - CST1 > NAME - CST2, if CST1 < CST2.  Notice that
1237e4b17023SJohn Marino 	       C1 and C2 are swapped in the call to compare_values.  */
1238e4b17023SJohn Marino 	    return compare_values_warnv (c2, c1, strict_overflow_p);
1239e4b17023SJohn Marino 	}
1240e4b17023SJohn Marino 
1241e4b17023SJohn Marino       gcc_unreachable ();
1242e4b17023SJohn Marino     }
1243e4b17023SJohn Marino 
1244e4b17023SJohn Marino   /* We cannot compare non-constants.  */
1245e4b17023SJohn Marino   if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
1246e4b17023SJohn Marino     return -2;
1247e4b17023SJohn Marino 
1248e4b17023SJohn Marino   if (!POINTER_TYPE_P (TREE_TYPE (val1)))
1249e4b17023SJohn Marino     {
1250e4b17023SJohn Marino       /* We cannot compare overflowed values, except for overflow
1251e4b17023SJohn Marino 	 infinities.  */
1252e4b17023SJohn Marino       if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
1253e4b17023SJohn Marino 	{
1254e4b17023SJohn Marino 	  if (strict_overflow_p != NULL)
1255e4b17023SJohn Marino 	    *strict_overflow_p = true;
1256e4b17023SJohn Marino 	  if (is_negative_overflow_infinity (val1))
1257e4b17023SJohn Marino 	    return is_negative_overflow_infinity (val2) ? 0 : -1;
1258e4b17023SJohn Marino 	  else if (is_negative_overflow_infinity (val2))
1259e4b17023SJohn Marino 	    return 1;
1260e4b17023SJohn Marino 	  else if (is_positive_overflow_infinity (val1))
1261e4b17023SJohn Marino 	    return is_positive_overflow_infinity (val2) ? 0 : 1;
1262e4b17023SJohn Marino 	  else if (is_positive_overflow_infinity (val2))
1263e4b17023SJohn Marino 	    return -1;
1264e4b17023SJohn Marino 	  return -2;
1265e4b17023SJohn Marino 	}
1266e4b17023SJohn Marino 
1267e4b17023SJohn Marino       return tree_int_cst_compare (val1, val2);
1268e4b17023SJohn Marino     }
1269e4b17023SJohn Marino   else
1270e4b17023SJohn Marino     {
1271e4b17023SJohn Marino       tree t;
1272e4b17023SJohn Marino 
1273e4b17023SJohn Marino       /* First see if VAL1 and VAL2 are not the same.  */
1274e4b17023SJohn Marino       if (val1 == val2 || operand_equal_p (val1, val2, 0))
1275e4b17023SJohn Marino 	return 0;
1276e4b17023SJohn Marino 
1277e4b17023SJohn Marino       /* If VAL1 is a lower address than VAL2, return -1.  */
1278e4b17023SJohn Marino       if (operand_less_p (val1, val2) == 1)
1279e4b17023SJohn Marino 	return -1;
1280e4b17023SJohn Marino 
1281e4b17023SJohn Marino       /* If VAL1 is a higher address than VAL2, return +1.  */
1282e4b17023SJohn Marino       if (operand_less_p (val2, val1) == 1)
1283e4b17023SJohn Marino 	return 1;
1284e4b17023SJohn Marino 
1285e4b17023SJohn Marino       /* If VAL1 is different than VAL2, return +2.
1286e4b17023SJohn Marino 	 For integer constants we either have already returned -1 or 1
1287e4b17023SJohn Marino 	 or they are equivalent.  We still might succeed in proving
1288e4b17023SJohn Marino 	 something about non-trivial operands.  */
1289e4b17023SJohn Marino       if (TREE_CODE (val1) != INTEGER_CST
1290e4b17023SJohn Marino 	  || TREE_CODE (val2) != INTEGER_CST)
1291e4b17023SJohn Marino 	{
1292e4b17023SJohn Marino           t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
1293e4b17023SJohn Marino 	  if (t && integer_onep (t))
1294e4b17023SJohn Marino 	    return 2;
1295e4b17023SJohn Marino 	}
1296e4b17023SJohn Marino 
1297e4b17023SJohn Marino       return -2;
1298e4b17023SJohn Marino     }
1299e4b17023SJohn Marino }
1300e4b17023SJohn Marino 
1301e4b17023SJohn Marino /* Compare values like compare_values_warnv, but treat comparisons of
1302e4b17023SJohn Marino    nonconstants which rely on undefined overflow as incomparable.  */
1303e4b17023SJohn Marino 
1304e4b17023SJohn Marino static int
compare_values(tree val1,tree val2)1305e4b17023SJohn Marino compare_values (tree val1, tree val2)
1306e4b17023SJohn Marino {
1307e4b17023SJohn Marino   bool sop;
1308e4b17023SJohn Marino   int ret;
1309e4b17023SJohn Marino 
1310e4b17023SJohn Marino   sop = false;
1311e4b17023SJohn Marino   ret = compare_values_warnv (val1, val2, &sop);
1312e4b17023SJohn Marino   if (sop
1313e4b17023SJohn Marino       && (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
1314e4b17023SJohn Marino     ret = -2;
1315e4b17023SJohn Marino   return ret;
1316e4b17023SJohn Marino }
1317e4b17023SJohn Marino 
1318e4b17023SJohn Marino 
1319e4b17023SJohn Marino /* Return 1 if VAL is inside value range MIN <= VAL <= MAX,
1320e4b17023SJohn Marino           0 if VAL is not inside [MIN, MAX],
1321e4b17023SJohn Marino 	 -2 if we cannot tell either way.
1322e4b17023SJohn Marino 
1323e4b17023SJohn Marino    Benchmark compile/20001226-1.c compilation time after changing this
1324e4b17023SJohn Marino    function.  */
1325e4b17023SJohn Marino 
1326e4b17023SJohn Marino static inline int
value_inside_range(tree val,tree min,tree max)1327e4b17023SJohn Marino value_inside_range (tree val, tree min, tree max)
1328e4b17023SJohn Marino {
1329e4b17023SJohn Marino   int cmp1, cmp2;
1330e4b17023SJohn Marino 
1331e4b17023SJohn Marino   cmp1 = operand_less_p (val, min);
1332e4b17023SJohn Marino   if (cmp1 == -2)
1333e4b17023SJohn Marino     return -2;
1334e4b17023SJohn Marino   if (cmp1 == 1)
1335e4b17023SJohn Marino     return 0;
1336e4b17023SJohn Marino 
1337e4b17023SJohn Marino   cmp2 = operand_less_p (max, val);
1338e4b17023SJohn Marino   if (cmp2 == -2)
1339e4b17023SJohn Marino     return -2;
1340e4b17023SJohn Marino 
1341e4b17023SJohn Marino   return !cmp2;
1342e4b17023SJohn Marino }
1343e4b17023SJohn Marino 
1344e4b17023SJohn Marino 
1345e4b17023SJohn Marino /* Return true if value ranges VR0 and VR1 have a non-empty
1346e4b17023SJohn Marino    intersection.
1347e4b17023SJohn Marino 
1348e4b17023SJohn Marino    Benchmark compile/20001226-1.c compilation time after changing this
1349e4b17023SJohn Marino    function.
1350e4b17023SJohn Marino    */
1351e4b17023SJohn Marino 
1352e4b17023SJohn Marino static inline bool
value_ranges_intersect_p(value_range_t * vr0,value_range_t * vr1)1353e4b17023SJohn Marino value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
1354e4b17023SJohn Marino {
1355e4b17023SJohn Marino   /* The value ranges do not intersect if the maximum of the first range is
1356e4b17023SJohn Marino      less than the minimum of the second range or vice versa.
1357e4b17023SJohn Marino      When those relations are unknown, we can't do any better.  */
1358e4b17023SJohn Marino   if (operand_less_p (vr0->max, vr1->min) != 0)
1359e4b17023SJohn Marino     return false;
1360e4b17023SJohn Marino   if (operand_less_p (vr1->max, vr0->min) != 0)
1361e4b17023SJohn Marino     return false;
1362e4b17023SJohn Marino   return true;
1363e4b17023SJohn Marino }
1364e4b17023SJohn Marino 
1365e4b17023SJohn Marino 
1366e4b17023SJohn Marino /* Return 1 if [MIN, MAX] includes the value zero, 0 if it does not
1367e4b17023SJohn Marino    include the value zero, -2 if we cannot tell.  */
1368e4b17023SJohn Marino 
1369e4b17023SJohn Marino static inline int
range_includes_zero_p(tree min,tree max)1370e4b17023SJohn Marino range_includes_zero_p (tree min, tree max)
1371e4b17023SJohn Marino {
1372e4b17023SJohn Marino   tree zero = build_int_cst (TREE_TYPE (min), 0);
1373e4b17023SJohn Marino   return value_inside_range (zero, min, max);
1374e4b17023SJohn Marino }
1375e4b17023SJohn Marino 
1376e4b17023SJohn Marino /* Return true if *VR is know to only contain nonnegative values.  */
1377e4b17023SJohn Marino 
1378e4b17023SJohn Marino static inline bool
value_range_nonnegative_p(value_range_t * vr)1379e4b17023SJohn Marino value_range_nonnegative_p (value_range_t *vr)
1380e4b17023SJohn Marino {
1381e4b17023SJohn Marino   /* Testing for VR_ANTI_RANGE is not useful here as any anti-range
1382e4b17023SJohn Marino      which would return a useful value should be encoded as a
1383e4b17023SJohn Marino      VR_RANGE.  */
1384e4b17023SJohn Marino   if (vr->type == VR_RANGE)
1385e4b17023SJohn Marino     {
1386e4b17023SJohn Marino       int result = compare_values (vr->min, integer_zero_node);
1387e4b17023SJohn Marino       return (result == 0 || result == 1);
1388e4b17023SJohn Marino     }
1389e4b17023SJohn Marino 
1390e4b17023SJohn Marino   return false;
1391e4b17023SJohn Marino }
1392e4b17023SJohn Marino 
1393e4b17023SJohn Marino /* Return true if T, an SSA_NAME, is known to be nonnegative.  Return
1394e4b17023SJohn Marino    false otherwise or if no value range information is available.  */
1395e4b17023SJohn Marino 
1396e4b17023SJohn Marino bool
ssa_name_nonnegative_p(const_tree t)1397e4b17023SJohn Marino ssa_name_nonnegative_p (const_tree t)
1398e4b17023SJohn Marino {
1399e4b17023SJohn Marino   value_range_t *vr = get_value_range (t);
1400e4b17023SJohn Marino 
1401e4b17023SJohn Marino   if (INTEGRAL_TYPE_P (t)
1402e4b17023SJohn Marino       && TYPE_UNSIGNED (t))
1403e4b17023SJohn Marino     return true;
1404e4b17023SJohn Marino 
1405e4b17023SJohn Marino   if (!vr)
1406e4b17023SJohn Marino     return false;
1407e4b17023SJohn Marino 
1408e4b17023SJohn Marino   return value_range_nonnegative_p (vr);
1409e4b17023SJohn Marino }
1410e4b17023SJohn Marino 
1411e4b17023SJohn Marino /* If *VR has a value rante that is a single constant value return that,
1412e4b17023SJohn Marino    otherwise return NULL_TREE.  */
1413e4b17023SJohn Marino 
1414e4b17023SJohn Marino static tree
value_range_constant_singleton(value_range_t * vr)1415e4b17023SJohn Marino value_range_constant_singleton (value_range_t *vr)
1416e4b17023SJohn Marino {
1417e4b17023SJohn Marino   if (vr->type == VR_RANGE
1418e4b17023SJohn Marino       && operand_equal_p (vr->min, vr->max, 0)
1419e4b17023SJohn Marino       && is_gimple_min_invariant (vr->min))
1420e4b17023SJohn Marino     return vr->min;
1421e4b17023SJohn Marino 
1422e4b17023SJohn Marino   return NULL_TREE;
1423e4b17023SJohn Marino }
1424e4b17023SJohn Marino 
1425e4b17023SJohn Marino /* If OP has a value range with a single constant value return that,
1426e4b17023SJohn Marino    otherwise return NULL_TREE.  This returns OP itself if OP is a
1427e4b17023SJohn Marino    constant.  */
1428e4b17023SJohn Marino 
1429e4b17023SJohn Marino static tree
op_with_constant_singleton_value_range(tree op)1430e4b17023SJohn Marino op_with_constant_singleton_value_range (tree op)
1431e4b17023SJohn Marino {
1432e4b17023SJohn Marino   if (is_gimple_min_invariant (op))
1433e4b17023SJohn Marino     return op;
1434e4b17023SJohn Marino 
1435e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
1436e4b17023SJohn Marino     return NULL_TREE;
1437e4b17023SJohn Marino 
1438e4b17023SJohn Marino   return value_range_constant_singleton (get_value_range (op));
1439e4b17023SJohn Marino }
1440e4b17023SJohn Marino 
1441e4b17023SJohn Marino /* Return true if op is in a boolean [0, 1] value-range.  */
1442e4b17023SJohn Marino 
1443e4b17023SJohn Marino static bool
op_with_boolean_value_range_p(tree op)1444e4b17023SJohn Marino op_with_boolean_value_range_p (tree op)
1445e4b17023SJohn Marino {
1446e4b17023SJohn Marino   value_range_t *vr;
1447e4b17023SJohn Marino 
1448e4b17023SJohn Marino   if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
1449e4b17023SJohn Marino     return true;
1450e4b17023SJohn Marino 
1451e4b17023SJohn Marino   if (integer_zerop (op)
1452e4b17023SJohn Marino       || integer_onep (op))
1453e4b17023SJohn Marino     return true;
1454e4b17023SJohn Marino 
1455e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
1456e4b17023SJohn Marino     return false;
1457e4b17023SJohn Marino 
1458e4b17023SJohn Marino   vr = get_value_range (op);
1459e4b17023SJohn Marino   return (vr->type == VR_RANGE
1460e4b17023SJohn Marino 	  && integer_zerop (vr->min)
1461e4b17023SJohn Marino 	  && integer_onep (vr->max));
1462e4b17023SJohn Marino }
1463e4b17023SJohn Marino 
1464e4b17023SJohn Marino /* Extract value range information from an ASSERT_EXPR EXPR and store
1465e4b17023SJohn Marino    it in *VR_P.  */
1466e4b17023SJohn Marino 
1467e4b17023SJohn Marino static void
extract_range_from_assert(value_range_t * vr_p,tree expr)1468e4b17023SJohn Marino extract_range_from_assert (value_range_t *vr_p, tree expr)
1469e4b17023SJohn Marino {
1470e4b17023SJohn Marino   tree var, cond, limit, min, max, type;
1471e4b17023SJohn Marino   value_range_t *var_vr, *limit_vr;
1472e4b17023SJohn Marino   enum tree_code cond_code;
1473e4b17023SJohn Marino 
1474e4b17023SJohn Marino   var = ASSERT_EXPR_VAR (expr);
1475e4b17023SJohn Marino   cond = ASSERT_EXPR_COND (expr);
1476e4b17023SJohn Marino 
1477e4b17023SJohn Marino   gcc_assert (COMPARISON_CLASS_P (cond));
1478e4b17023SJohn Marino 
1479e4b17023SJohn Marino   /* Find VAR in the ASSERT_EXPR conditional.  */
1480e4b17023SJohn Marino   if (var == TREE_OPERAND (cond, 0)
1481e4b17023SJohn Marino       || TREE_CODE (TREE_OPERAND (cond, 0)) == PLUS_EXPR
1482e4b17023SJohn Marino       || TREE_CODE (TREE_OPERAND (cond, 0)) == NOP_EXPR)
1483e4b17023SJohn Marino     {
1484e4b17023SJohn Marino       /* If the predicate is of the form VAR COMP LIMIT, then we just
1485e4b17023SJohn Marino 	 take LIMIT from the RHS and use the same comparison code.  */
1486e4b17023SJohn Marino       cond_code = TREE_CODE (cond);
1487e4b17023SJohn Marino       limit = TREE_OPERAND (cond, 1);
1488e4b17023SJohn Marino       cond = TREE_OPERAND (cond, 0);
1489e4b17023SJohn Marino     }
1490e4b17023SJohn Marino   else
1491e4b17023SJohn Marino     {
1492e4b17023SJohn Marino       /* If the predicate is of the form LIMIT COMP VAR, then we need
1493e4b17023SJohn Marino 	 to flip around the comparison code to create the proper range
1494e4b17023SJohn Marino 	 for VAR.  */
1495e4b17023SJohn Marino       cond_code = swap_tree_comparison (TREE_CODE (cond));
1496e4b17023SJohn Marino       limit = TREE_OPERAND (cond, 0);
1497e4b17023SJohn Marino       cond = TREE_OPERAND (cond, 1);
1498e4b17023SJohn Marino     }
1499e4b17023SJohn Marino 
1500e4b17023SJohn Marino   limit = avoid_overflow_infinity (limit);
1501e4b17023SJohn Marino 
1502e4b17023SJohn Marino   type = TREE_TYPE (var);
1503e4b17023SJohn Marino   gcc_assert (limit != var);
1504e4b17023SJohn Marino 
1505e4b17023SJohn Marino   /* For pointer arithmetic, we only keep track of pointer equality
1506e4b17023SJohn Marino      and inequality.  */
1507e4b17023SJohn Marino   if (POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
1508e4b17023SJohn Marino     {
1509e4b17023SJohn Marino       set_value_range_to_varying (vr_p);
1510e4b17023SJohn Marino       return;
1511e4b17023SJohn Marino     }
1512e4b17023SJohn Marino 
1513e4b17023SJohn Marino   /* If LIMIT is another SSA name and LIMIT has a range of its own,
1514e4b17023SJohn Marino      try to use LIMIT's range to avoid creating symbolic ranges
1515e4b17023SJohn Marino      unnecessarily. */
1516e4b17023SJohn Marino   limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
1517e4b17023SJohn Marino 
1518e4b17023SJohn Marino   /* LIMIT's range is only interesting if it has any useful information.  */
1519e4b17023SJohn Marino   if (limit_vr
1520e4b17023SJohn Marino       && (limit_vr->type == VR_UNDEFINED
1521e4b17023SJohn Marino 	  || limit_vr->type == VR_VARYING
1522e4b17023SJohn Marino 	  || symbolic_range_p (limit_vr)))
1523e4b17023SJohn Marino     limit_vr = NULL;
1524e4b17023SJohn Marino 
1525e4b17023SJohn Marino   /* Initially, the new range has the same set of equivalences of
1526e4b17023SJohn Marino      VAR's range.  This will be revised before returning the final
1527e4b17023SJohn Marino      value.  Since assertions may be chained via mutually exclusive
1528e4b17023SJohn Marino      predicates, we will need to trim the set of equivalences before
1529e4b17023SJohn Marino      we are done.  */
1530e4b17023SJohn Marino   gcc_assert (vr_p->equiv == NULL);
1531e4b17023SJohn Marino   add_equivalence (&vr_p->equiv, var);
1532e4b17023SJohn Marino 
1533e4b17023SJohn Marino   /* Extract a new range based on the asserted comparison for VAR and
1534e4b17023SJohn Marino      LIMIT's value range.  Notice that if LIMIT has an anti-range, we
1535e4b17023SJohn Marino      will only use it for equality comparisons (EQ_EXPR).  For any
1536e4b17023SJohn Marino      other kind of assertion, we cannot derive a range from LIMIT's
1537e4b17023SJohn Marino      anti-range that can be used to describe the new range.  For
1538e4b17023SJohn Marino      instance, ASSERT_EXPR <x_2, x_2 <= b_4>.  If b_4 is ~[2, 10],
1539e4b17023SJohn Marino      then b_4 takes on the ranges [-INF, 1] and [11, +INF].  There is
1540e4b17023SJohn Marino      no single range for x_2 that could describe LE_EXPR, so we might
1541e4b17023SJohn Marino      as well build the range [b_4, +INF] for it.
1542e4b17023SJohn Marino      One special case we handle is extracting a range from a
1543e4b17023SJohn Marino      range test encoded as (unsigned)var + CST <= limit.  */
1544e4b17023SJohn Marino   if (TREE_CODE (cond) == NOP_EXPR
1545e4b17023SJohn Marino       || TREE_CODE (cond) == PLUS_EXPR)
1546e4b17023SJohn Marino     {
1547e4b17023SJohn Marino       if (TREE_CODE (cond) == PLUS_EXPR)
1548e4b17023SJohn Marino         {
1549e4b17023SJohn Marino           min = fold_build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (cond, 1)),
1550e4b17023SJohn Marino 			     TREE_OPERAND (cond, 1));
1551e4b17023SJohn Marino           max = int_const_binop (PLUS_EXPR, limit, min);
1552e4b17023SJohn Marino 	  cond = TREE_OPERAND (cond, 0);
1553e4b17023SJohn Marino 	}
1554e4b17023SJohn Marino       else
1555e4b17023SJohn Marino 	{
1556e4b17023SJohn Marino 	  min = build_int_cst (TREE_TYPE (var), 0);
1557e4b17023SJohn Marino 	  max = limit;
1558e4b17023SJohn Marino 	}
1559e4b17023SJohn Marino 
1560e4b17023SJohn Marino       /* Make sure to not set TREE_OVERFLOW on the final type
1561e4b17023SJohn Marino 	 conversion.  We are willingly interpreting large positive
1562e4b17023SJohn Marino 	 unsigned values as negative singed values here.  */
1563e4b17023SJohn Marino       min = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (min),
1564e4b17023SJohn Marino 				   0, false);
1565e4b17023SJohn Marino       max = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (max),
1566e4b17023SJohn Marino 				   0, false);
1567e4b17023SJohn Marino 
1568e4b17023SJohn Marino       /* We can transform a max, min range to an anti-range or
1569e4b17023SJohn Marino          vice-versa.  Use set_and_canonicalize_value_range which does
1570e4b17023SJohn Marino 	 this for us.  */
1571e4b17023SJohn Marino       if (cond_code == LE_EXPR)
1572e4b17023SJohn Marino         set_and_canonicalize_value_range (vr_p, VR_RANGE,
1573e4b17023SJohn Marino 					  min, max, vr_p->equiv);
1574e4b17023SJohn Marino       else if (cond_code == GT_EXPR)
1575e4b17023SJohn Marino         set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
1576e4b17023SJohn Marino 					  min, max, vr_p->equiv);
1577e4b17023SJohn Marino       else
1578e4b17023SJohn Marino 	gcc_unreachable ();
1579e4b17023SJohn Marino     }
1580e4b17023SJohn Marino   else if (cond_code == EQ_EXPR)
1581e4b17023SJohn Marino     {
1582e4b17023SJohn Marino       enum value_range_type range_type;
1583e4b17023SJohn Marino 
1584e4b17023SJohn Marino       if (limit_vr)
1585e4b17023SJohn Marino 	{
1586e4b17023SJohn Marino 	  range_type = limit_vr->type;
1587e4b17023SJohn Marino 	  min = limit_vr->min;
1588e4b17023SJohn Marino 	  max = limit_vr->max;
1589e4b17023SJohn Marino 	}
1590e4b17023SJohn Marino       else
1591e4b17023SJohn Marino 	{
1592e4b17023SJohn Marino 	  range_type = VR_RANGE;
1593e4b17023SJohn Marino 	  min = limit;
1594e4b17023SJohn Marino 	  max = limit;
1595e4b17023SJohn Marino 	}
1596e4b17023SJohn Marino 
1597e4b17023SJohn Marino       set_value_range (vr_p, range_type, min, max, vr_p->equiv);
1598e4b17023SJohn Marino 
1599e4b17023SJohn Marino       /* When asserting the equality VAR == LIMIT and LIMIT is another
1600e4b17023SJohn Marino 	 SSA name, the new range will also inherit the equivalence set
1601e4b17023SJohn Marino 	 from LIMIT.  */
1602e4b17023SJohn Marino       if (TREE_CODE (limit) == SSA_NAME)
1603e4b17023SJohn Marino 	add_equivalence (&vr_p->equiv, limit);
1604e4b17023SJohn Marino     }
1605e4b17023SJohn Marino   else if (cond_code == NE_EXPR)
1606e4b17023SJohn Marino     {
1607e4b17023SJohn Marino       /* As described above, when LIMIT's range is an anti-range and
1608e4b17023SJohn Marino 	 this assertion is an inequality (NE_EXPR), then we cannot
1609e4b17023SJohn Marino 	 derive anything from the anti-range.  For instance, if
1610e4b17023SJohn Marino 	 LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
1611e4b17023SJohn Marino 	 not imply that VAR's range is [0, 0].  So, in the case of
1612e4b17023SJohn Marino 	 anti-ranges, we just assert the inequality using LIMIT and
1613e4b17023SJohn Marino 	 not its anti-range.
1614e4b17023SJohn Marino 
1615e4b17023SJohn Marino 	 If LIMIT_VR is a range, we can only use it to build a new
1616e4b17023SJohn Marino 	 anti-range if LIMIT_VR is a single-valued range.  For
1617e4b17023SJohn Marino 	 instance, if LIMIT_VR is [0, 1], the predicate
1618e4b17023SJohn Marino 	 VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
1619e4b17023SJohn Marino 	 Rather, it means that for value 0 VAR should be ~[0, 0]
1620e4b17023SJohn Marino 	 and for value 1, VAR should be ~[1, 1].  We cannot
1621e4b17023SJohn Marino 	 represent these ranges.
1622e4b17023SJohn Marino 
1623e4b17023SJohn Marino 	 The only situation in which we can build a valid
1624e4b17023SJohn Marino 	 anti-range is when LIMIT_VR is a single-valued range
1625e4b17023SJohn Marino 	 (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX).  In that case,
1626e4b17023SJohn Marino 	 build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX].  */
1627e4b17023SJohn Marino       if (limit_vr
1628e4b17023SJohn Marino 	  && limit_vr->type == VR_RANGE
1629e4b17023SJohn Marino 	  && compare_values (limit_vr->min, limit_vr->max) == 0)
1630e4b17023SJohn Marino 	{
1631e4b17023SJohn Marino 	  min = limit_vr->min;
1632e4b17023SJohn Marino 	  max = limit_vr->max;
1633e4b17023SJohn Marino 	}
1634e4b17023SJohn Marino       else
1635e4b17023SJohn Marino 	{
1636e4b17023SJohn Marino 	  /* In any other case, we cannot use LIMIT's range to build a
1637e4b17023SJohn Marino 	     valid anti-range.  */
1638e4b17023SJohn Marino 	  min = max = limit;
1639e4b17023SJohn Marino 	}
1640e4b17023SJohn Marino 
1641e4b17023SJohn Marino       /* If MIN and MAX cover the whole range for their type, then
1642e4b17023SJohn Marino 	 just use the original LIMIT.  */
1643e4b17023SJohn Marino       if (INTEGRAL_TYPE_P (type)
1644e4b17023SJohn Marino 	  && vrp_val_is_min (min)
1645e4b17023SJohn Marino 	  && vrp_val_is_max (max))
1646e4b17023SJohn Marino 	min = max = limit;
1647e4b17023SJohn Marino 
1648e4b17023SJohn Marino       set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
1649e4b17023SJohn Marino     }
1650e4b17023SJohn Marino   else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
1651e4b17023SJohn Marino     {
1652e4b17023SJohn Marino       min = TYPE_MIN_VALUE (type);
1653e4b17023SJohn Marino 
1654e4b17023SJohn Marino       if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
1655e4b17023SJohn Marino 	max = limit;
1656e4b17023SJohn Marino       else
1657e4b17023SJohn Marino 	{
1658e4b17023SJohn Marino 	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
1659e4b17023SJohn Marino 	     range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
1660e4b17023SJohn Marino 	     LT_EXPR.  */
1661e4b17023SJohn Marino 	  max = limit_vr->max;
1662e4b17023SJohn Marino 	}
1663e4b17023SJohn Marino 
1664e4b17023SJohn Marino       /* If the maximum value forces us to be out of bounds, simply punt.
1665e4b17023SJohn Marino 	 It would be pointless to try and do anything more since this
1666e4b17023SJohn Marino 	 all should be optimized away above us.  */
1667e4b17023SJohn Marino       if ((cond_code == LT_EXPR
1668e4b17023SJohn Marino 	   && compare_values (max, min) == 0)
1669e4b17023SJohn Marino 	  || (CONSTANT_CLASS_P (max) && TREE_OVERFLOW (max)))
1670e4b17023SJohn Marino 	set_value_range_to_varying (vr_p);
1671e4b17023SJohn Marino       else
1672e4b17023SJohn Marino 	{
1673e4b17023SJohn Marino 	  /* For LT_EXPR, we create the range [MIN, MAX - 1].  */
1674e4b17023SJohn Marino 	  if (cond_code == LT_EXPR)
1675e4b17023SJohn Marino 	    {
1676e4b17023SJohn Marino 	      if (TYPE_PRECISION (TREE_TYPE (max)) == 1
1677e4b17023SJohn Marino 		  && !TYPE_UNSIGNED (TREE_TYPE (max)))
1678e4b17023SJohn Marino 		max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max,
1679e4b17023SJohn Marino 				   build_int_cst (TREE_TYPE (max), -1));
1680e4b17023SJohn Marino 	      else
1681e4b17023SJohn Marino 		max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max,
1682e4b17023SJohn Marino 				   build_int_cst (TREE_TYPE (max), 1));
1683e4b17023SJohn Marino 	      if (EXPR_P (max))
1684e4b17023SJohn Marino 		TREE_NO_WARNING (max) = 1;
1685e4b17023SJohn Marino 	    }
1686e4b17023SJohn Marino 
1687e4b17023SJohn Marino 	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1688e4b17023SJohn Marino 	}
1689e4b17023SJohn Marino     }
1690e4b17023SJohn Marino   else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
1691e4b17023SJohn Marino     {
1692e4b17023SJohn Marino       max = TYPE_MAX_VALUE (type);
1693e4b17023SJohn Marino 
1694e4b17023SJohn Marino       if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
1695e4b17023SJohn Marino 	min = limit;
1696e4b17023SJohn Marino       else
1697e4b17023SJohn Marino 	{
1698e4b17023SJohn Marino 	  /* If LIMIT_VR is of the form [N1, N2], we need to build the
1699e4b17023SJohn Marino 	     range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
1700e4b17023SJohn Marino 	     GT_EXPR.  */
1701e4b17023SJohn Marino 	  min = limit_vr->min;
1702e4b17023SJohn Marino 	}
1703e4b17023SJohn Marino 
1704e4b17023SJohn Marino       /* If the minimum value forces us to be out of bounds, simply punt.
1705e4b17023SJohn Marino 	 It would be pointless to try and do anything more since this
1706e4b17023SJohn Marino 	 all should be optimized away above us.  */
1707e4b17023SJohn Marino       if ((cond_code == GT_EXPR
1708e4b17023SJohn Marino 	   && compare_values (min, max) == 0)
1709e4b17023SJohn Marino 	  || (CONSTANT_CLASS_P (min) && TREE_OVERFLOW (min)))
1710e4b17023SJohn Marino 	set_value_range_to_varying (vr_p);
1711e4b17023SJohn Marino       else
1712e4b17023SJohn Marino 	{
1713e4b17023SJohn Marino 	  /* For GT_EXPR, we create the range [MIN + 1, MAX].  */
1714e4b17023SJohn Marino 	  if (cond_code == GT_EXPR)
1715e4b17023SJohn Marino 	    {
1716e4b17023SJohn Marino 	      if (TYPE_PRECISION (TREE_TYPE (min)) == 1
1717e4b17023SJohn Marino 		  && !TYPE_UNSIGNED (TREE_TYPE (min)))
1718e4b17023SJohn Marino 		min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min,
1719e4b17023SJohn Marino 				   build_int_cst (TREE_TYPE (min), -1));
1720e4b17023SJohn Marino 	      else
1721e4b17023SJohn Marino 		min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min,
1722e4b17023SJohn Marino 				   build_int_cst (TREE_TYPE (min), 1));
1723e4b17023SJohn Marino 	      if (EXPR_P (min))
1724e4b17023SJohn Marino 		TREE_NO_WARNING (min) = 1;
1725e4b17023SJohn Marino 	    }
1726e4b17023SJohn Marino 
1727e4b17023SJohn Marino 	  set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1728e4b17023SJohn Marino 	}
1729e4b17023SJohn Marino     }
1730e4b17023SJohn Marino   else
1731e4b17023SJohn Marino     gcc_unreachable ();
1732e4b17023SJohn Marino 
1733e4b17023SJohn Marino   /* If VAR already had a known range, it may happen that the new
1734e4b17023SJohn Marino      range we have computed and VAR's range are not compatible.  For
1735e4b17023SJohn Marino      instance,
1736e4b17023SJohn Marino 
1737e4b17023SJohn Marino 	if (p_5 == NULL)
1738e4b17023SJohn Marino 	  p_6 = ASSERT_EXPR <p_5, p_5 == NULL>;
1739e4b17023SJohn Marino 	  x_7 = p_6->fld;
1740e4b17023SJohn Marino 	  p_8 = ASSERT_EXPR <p_6, p_6 != NULL>;
1741e4b17023SJohn Marino 
1742e4b17023SJohn Marino      While the above comes from a faulty program, it will cause an ICE
1743e4b17023SJohn Marino      later because p_8 and p_6 will have incompatible ranges and at
1744e4b17023SJohn Marino      the same time will be considered equivalent.  A similar situation
1745e4b17023SJohn Marino      would arise from
1746e4b17023SJohn Marino 
1747e4b17023SJohn Marino      	if (i_5 > 10)
1748e4b17023SJohn Marino 	  i_6 = ASSERT_EXPR <i_5, i_5 > 10>;
1749e4b17023SJohn Marino 	  if (i_5 < 5)
1750e4b17023SJohn Marino 	    i_7 = ASSERT_EXPR <i_6, i_6 < 5>;
1751e4b17023SJohn Marino 
1752e4b17023SJohn Marino      Again i_6 and i_7 will have incompatible ranges.  It would be
1753e4b17023SJohn Marino      pointless to try and do anything with i_7's range because
1754e4b17023SJohn Marino      anything dominated by 'if (i_5 < 5)' will be optimized away.
1755e4b17023SJohn Marino      Note, due to the wa in which simulation proceeds, the statement
1756e4b17023SJohn Marino      i_7 = ASSERT_EXPR <...> we would never be visited because the
1757e4b17023SJohn Marino      conditional 'if (i_5 < 5)' always evaluates to false.  However,
1758e4b17023SJohn Marino      this extra check does not hurt and may protect against future
1759e4b17023SJohn Marino      changes to VRP that may get into a situation similar to the
1760e4b17023SJohn Marino      NULL pointer dereference example.
1761e4b17023SJohn Marino 
1762e4b17023SJohn Marino      Note that these compatibility tests are only needed when dealing
1763e4b17023SJohn Marino      with ranges or a mix of range and anti-range.  If VAR_VR and VR_P
1764e4b17023SJohn Marino      are both anti-ranges, they will always be compatible, because two
1765e4b17023SJohn Marino      anti-ranges will always have a non-empty intersection.  */
1766e4b17023SJohn Marino 
1767e4b17023SJohn Marino   var_vr = get_value_range (var);
1768e4b17023SJohn Marino 
1769e4b17023SJohn Marino   /* We may need to make adjustments when VR_P and VAR_VR are numeric
1770e4b17023SJohn Marino      ranges or anti-ranges.  */
1771e4b17023SJohn Marino   if (vr_p->type == VR_VARYING
1772e4b17023SJohn Marino       || vr_p->type == VR_UNDEFINED
1773e4b17023SJohn Marino       || var_vr->type == VR_VARYING
1774e4b17023SJohn Marino       || var_vr->type == VR_UNDEFINED
1775e4b17023SJohn Marino       || symbolic_range_p (vr_p)
1776e4b17023SJohn Marino       || symbolic_range_p (var_vr))
1777e4b17023SJohn Marino     return;
1778e4b17023SJohn Marino 
1779e4b17023SJohn Marino   if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
1780e4b17023SJohn Marino     {
1781e4b17023SJohn Marino       /* If the two ranges have a non-empty intersection, we can
1782e4b17023SJohn Marino 	 refine the resulting range.  Since the assert expression
1783e4b17023SJohn Marino 	 creates an equivalency and at the same time it asserts a
1784e4b17023SJohn Marino 	 predicate, we can take the intersection of the two ranges to
1785e4b17023SJohn Marino 	 get better precision.  */
1786e4b17023SJohn Marino       if (value_ranges_intersect_p (var_vr, vr_p))
1787e4b17023SJohn Marino 	{
1788e4b17023SJohn Marino 	  /* Use the larger of the two minimums.  */
1789e4b17023SJohn Marino 	  if (compare_values (vr_p->min, var_vr->min) == -1)
1790e4b17023SJohn Marino 	    min = var_vr->min;
1791e4b17023SJohn Marino 	  else
1792e4b17023SJohn Marino 	    min = vr_p->min;
1793e4b17023SJohn Marino 
1794e4b17023SJohn Marino 	  /* Use the smaller of the two maximums.  */
1795e4b17023SJohn Marino 	  if (compare_values (vr_p->max, var_vr->max) == 1)
1796e4b17023SJohn Marino 	    max = var_vr->max;
1797e4b17023SJohn Marino 	  else
1798e4b17023SJohn Marino 	    max = vr_p->max;
1799e4b17023SJohn Marino 
1800e4b17023SJohn Marino 	  set_value_range (vr_p, vr_p->type, min, max, vr_p->equiv);
1801e4b17023SJohn Marino 	}
1802e4b17023SJohn Marino       else
1803e4b17023SJohn Marino 	{
1804e4b17023SJohn Marino 	  /* The two ranges do not intersect, set the new range to
1805e4b17023SJohn Marino 	     VARYING, because we will not be able to do anything
1806e4b17023SJohn Marino 	     meaningful with it.  */
1807e4b17023SJohn Marino 	  set_value_range_to_varying (vr_p);
1808e4b17023SJohn Marino 	}
1809e4b17023SJohn Marino     }
1810e4b17023SJohn Marino   else if ((var_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
1811e4b17023SJohn Marino            || (var_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
1812e4b17023SJohn Marino     {
1813e4b17023SJohn Marino       /* A range and an anti-range will cancel each other only if
1814e4b17023SJohn Marino 	 their ends are the same.  For instance, in the example above,
1815e4b17023SJohn Marino 	 p_8's range ~[0, 0] and p_6's range [0, 0] are incompatible,
1816e4b17023SJohn Marino 	 so VR_P should be set to VR_VARYING.  */
1817e4b17023SJohn Marino       if (compare_values (var_vr->min, vr_p->min) == 0
1818e4b17023SJohn Marino 	  && compare_values (var_vr->max, vr_p->max) == 0)
1819e4b17023SJohn Marino 	set_value_range_to_varying (vr_p);
1820e4b17023SJohn Marino       else
1821e4b17023SJohn Marino 	{
1822e4b17023SJohn Marino 	  tree min, max, anti_min, anti_max, real_min, real_max;
1823e4b17023SJohn Marino 	  int cmp;
1824e4b17023SJohn Marino 
1825e4b17023SJohn Marino 	  /* We want to compute the logical AND of the two ranges;
1826e4b17023SJohn Marino 	     there are three cases to consider.
1827e4b17023SJohn Marino 
1828e4b17023SJohn Marino 
1829e4b17023SJohn Marino 	     1. The VR_ANTI_RANGE range is completely within the
1830e4b17023SJohn Marino 		VR_RANGE and the endpoints of the ranges are
1831e4b17023SJohn Marino 		different.  In that case the resulting range
1832e4b17023SJohn Marino 		should be whichever range is more precise.
1833e4b17023SJohn Marino 		Typically that will be the VR_RANGE.
1834e4b17023SJohn Marino 
1835e4b17023SJohn Marino 	     2. The VR_ANTI_RANGE is completely disjoint from
1836e4b17023SJohn Marino 		the VR_RANGE.  In this case the resulting range
1837e4b17023SJohn Marino 		should be the VR_RANGE.
1838e4b17023SJohn Marino 
1839e4b17023SJohn Marino 	     3. There is some overlap between the VR_ANTI_RANGE
1840e4b17023SJohn Marino 		and the VR_RANGE.
1841e4b17023SJohn Marino 
1842e4b17023SJohn Marino 		3a. If the high limit of the VR_ANTI_RANGE resides
1843e4b17023SJohn Marino 		    within the VR_RANGE, then the result is a new
1844e4b17023SJohn Marino 		    VR_RANGE starting at the high limit of the
1845e4b17023SJohn Marino 		    VR_ANTI_RANGE + 1 and extending to the
1846e4b17023SJohn Marino 		    high limit of the original VR_RANGE.
1847e4b17023SJohn Marino 
1848e4b17023SJohn Marino 		3b. If the low limit of the VR_ANTI_RANGE resides
1849e4b17023SJohn Marino 		    within the VR_RANGE, then the result is a new
1850e4b17023SJohn Marino 		    VR_RANGE starting at the low limit of the original
1851e4b17023SJohn Marino 		    VR_RANGE and extending to the low limit of the
1852e4b17023SJohn Marino 		    VR_ANTI_RANGE - 1.  */
1853e4b17023SJohn Marino 	  if (vr_p->type == VR_ANTI_RANGE)
1854e4b17023SJohn Marino 	    {
1855e4b17023SJohn Marino 	      anti_min = vr_p->min;
1856e4b17023SJohn Marino 	      anti_max = vr_p->max;
1857e4b17023SJohn Marino 	      real_min = var_vr->min;
1858e4b17023SJohn Marino 	      real_max = var_vr->max;
1859e4b17023SJohn Marino 	    }
1860e4b17023SJohn Marino 	  else
1861e4b17023SJohn Marino 	    {
1862e4b17023SJohn Marino 	      anti_min = var_vr->min;
1863e4b17023SJohn Marino 	      anti_max = var_vr->max;
1864e4b17023SJohn Marino 	      real_min = vr_p->min;
1865e4b17023SJohn Marino 	      real_max = vr_p->max;
1866e4b17023SJohn Marino 	    }
1867e4b17023SJohn Marino 
1868e4b17023SJohn Marino 
1869e4b17023SJohn Marino 	  /* Case 1, VR_ANTI_RANGE completely within VR_RANGE,
1870e4b17023SJohn Marino 	     not including any endpoints.  */
1871e4b17023SJohn Marino 	  if (compare_values (anti_max, real_max) == -1
1872e4b17023SJohn Marino 	      && compare_values (anti_min, real_min) == 1)
1873e4b17023SJohn Marino 	    {
1874e4b17023SJohn Marino 	      /* If the range is covering the whole valid range of
1875e4b17023SJohn Marino 		 the type keep the anti-range.  */
1876e4b17023SJohn Marino 	      if (!vrp_val_is_min (real_min)
1877e4b17023SJohn Marino 		  || !vrp_val_is_max (real_max))
1878e4b17023SJohn Marino 	        set_value_range (vr_p, VR_RANGE, real_min,
1879e4b17023SJohn Marino 				 real_max, vr_p->equiv);
1880e4b17023SJohn Marino 	    }
1881e4b17023SJohn Marino 	  /* Case 2, VR_ANTI_RANGE completely disjoint from
1882e4b17023SJohn Marino 	     VR_RANGE.  */
1883e4b17023SJohn Marino 	  else if (compare_values (anti_min, real_max) == 1
1884e4b17023SJohn Marino 		   || compare_values (anti_max, real_min) == -1)
1885e4b17023SJohn Marino 	    {
1886e4b17023SJohn Marino 	      set_value_range (vr_p, VR_RANGE, real_min,
1887e4b17023SJohn Marino 			       real_max, vr_p->equiv);
1888e4b17023SJohn Marino 	    }
1889e4b17023SJohn Marino 	  /* Case 3a, the anti-range extends into the low
1890e4b17023SJohn Marino 	     part of the real range.  Thus creating a new
1891e4b17023SJohn Marino 	     low for the real range.  */
1892e4b17023SJohn Marino 	  else if (((cmp = compare_values (anti_max, real_min)) == 1
1893e4b17023SJohn Marino 		    || cmp == 0)
1894e4b17023SJohn Marino 		   && compare_values (anti_max, real_max) == -1)
1895e4b17023SJohn Marino 	    {
1896e4b17023SJohn Marino 	      gcc_assert (!is_positive_overflow_infinity (anti_max));
1897e4b17023SJohn Marino 	      if (needs_overflow_infinity (TREE_TYPE (anti_max))
1898e4b17023SJohn Marino 		  && vrp_val_is_max (anti_max))
1899e4b17023SJohn Marino 		{
1900e4b17023SJohn Marino 		  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
1901e4b17023SJohn Marino 		    {
1902e4b17023SJohn Marino 		      set_value_range_to_varying (vr_p);
1903e4b17023SJohn Marino 		      return;
1904e4b17023SJohn Marino 		    }
1905e4b17023SJohn Marino 		  min = positive_overflow_infinity (TREE_TYPE (var_vr->min));
1906e4b17023SJohn Marino 		}
1907e4b17023SJohn Marino 	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
1908e4b17023SJohn Marino 		{
1909e4b17023SJohn Marino 		  if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
1910e4b17023SJohn Marino 		      && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
1911e4b17023SJohn Marino 		    min = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
1912e4b17023SJohn Marino 				       anti_max,
1913e4b17023SJohn Marino 				       build_int_cst (TREE_TYPE (var_vr->min),
1914e4b17023SJohn Marino 						      -1));
1915e4b17023SJohn Marino 		  else
1916e4b17023SJohn Marino 		    min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
1917e4b17023SJohn Marino 				       anti_max,
1918e4b17023SJohn Marino 				       build_int_cst (TREE_TYPE (var_vr->min),
1919e4b17023SJohn Marino 						      1));
1920e4b17023SJohn Marino 		}
1921e4b17023SJohn Marino 	      else
1922e4b17023SJohn Marino 		min = fold_build_pointer_plus_hwi (anti_max, 1);
1923e4b17023SJohn Marino 	      max = real_max;
1924e4b17023SJohn Marino 	      set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1925e4b17023SJohn Marino 	    }
1926e4b17023SJohn Marino 	  /* Case 3b, the anti-range extends into the high
1927e4b17023SJohn Marino 	     part of the real range.  Thus creating a new
1928e4b17023SJohn Marino 	     higher for the real range.  */
1929e4b17023SJohn Marino 	  else if (compare_values (anti_min, real_min) == 1
1930e4b17023SJohn Marino 		   && ((cmp = compare_values (anti_min, real_max)) == -1
1931e4b17023SJohn Marino 		       || cmp == 0))
1932e4b17023SJohn Marino 	    {
1933e4b17023SJohn Marino 	      gcc_assert (!is_negative_overflow_infinity (anti_min));
1934e4b17023SJohn Marino 	      if (needs_overflow_infinity (TREE_TYPE (anti_min))
1935e4b17023SJohn Marino 		  && vrp_val_is_min (anti_min))
1936e4b17023SJohn Marino 		{
1937e4b17023SJohn Marino 		  if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
1938e4b17023SJohn Marino 		    {
1939e4b17023SJohn Marino 		      set_value_range_to_varying (vr_p);
1940e4b17023SJohn Marino 		      return;
1941e4b17023SJohn Marino 		    }
1942e4b17023SJohn Marino 		  max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
1943e4b17023SJohn Marino 		}
1944e4b17023SJohn Marino 	      else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
1945e4b17023SJohn Marino 		{
1946e4b17023SJohn Marino 		  if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
1947e4b17023SJohn Marino 		      && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
1948e4b17023SJohn Marino 		    max = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
1949e4b17023SJohn Marino 				       anti_min,
1950e4b17023SJohn Marino 				       build_int_cst (TREE_TYPE (var_vr->min),
1951e4b17023SJohn Marino 						      -1));
1952e4b17023SJohn Marino 		  else
1953e4b17023SJohn Marino 		    max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
1954e4b17023SJohn Marino 				       anti_min,
1955e4b17023SJohn Marino 				       build_int_cst (TREE_TYPE (var_vr->min),
1956e4b17023SJohn Marino 						      1));
1957e4b17023SJohn Marino 		}
1958e4b17023SJohn Marino 	      else
1959e4b17023SJohn Marino 		max = fold_build_pointer_plus_hwi (anti_min, -1);
1960e4b17023SJohn Marino 	      min = real_min;
1961e4b17023SJohn Marino 	      set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1962e4b17023SJohn Marino 	    }
1963e4b17023SJohn Marino 	}
1964e4b17023SJohn Marino     }
1965e4b17023SJohn Marino }
1966e4b17023SJohn Marino 
1967e4b17023SJohn Marino 
1968e4b17023SJohn Marino /* Extract range information from SSA name VAR and store it in VR.  If
1969e4b17023SJohn Marino    VAR has an interesting range, use it.  Otherwise, create the
1970e4b17023SJohn Marino    range [VAR, VAR] and return it.  This is useful in situations where
1971e4b17023SJohn Marino    we may have conditionals testing values of VARYING names.  For
1972e4b17023SJohn Marino    instance,
1973e4b17023SJohn Marino 
1974e4b17023SJohn Marino    	x_3 = y_5;
1975e4b17023SJohn Marino 	if (x_3 > y_5)
1976e4b17023SJohn Marino 	  ...
1977e4b17023SJohn Marino 
1978e4b17023SJohn Marino     Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
1979e4b17023SJohn Marino     always false.  */
1980e4b17023SJohn Marino 
1981e4b17023SJohn Marino static void
extract_range_from_ssa_name(value_range_t * vr,tree var)1982e4b17023SJohn Marino extract_range_from_ssa_name (value_range_t *vr, tree var)
1983e4b17023SJohn Marino {
1984e4b17023SJohn Marino   value_range_t *var_vr = get_value_range (var);
1985e4b17023SJohn Marino 
1986e4b17023SJohn Marino   if (var_vr->type != VR_UNDEFINED && var_vr->type != VR_VARYING)
1987e4b17023SJohn Marino     copy_value_range (vr, var_vr);
1988e4b17023SJohn Marino   else
1989e4b17023SJohn Marino     set_value_range (vr, VR_RANGE, var, var, NULL);
1990e4b17023SJohn Marino 
1991e4b17023SJohn Marino   add_equivalence (&vr->equiv, var);
1992e4b17023SJohn Marino }
1993e4b17023SJohn Marino 
1994e4b17023SJohn Marino 
1995e4b17023SJohn Marino /* Wrapper around int_const_binop.  If the operation overflows and we
1996e4b17023SJohn Marino    are not using wrapping arithmetic, then adjust the result to be
1997e4b17023SJohn Marino    -INF or +INF depending on CODE, VAL1 and VAL2.  This can return
1998e4b17023SJohn Marino    NULL_TREE if we need to use an overflow infinity representation but
1999e4b17023SJohn Marino    the type does not support it.  */
2000e4b17023SJohn Marino 
2001e4b17023SJohn Marino static tree
vrp_int_const_binop(enum tree_code code,tree val1,tree val2)2002e4b17023SJohn Marino vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
2003e4b17023SJohn Marino {
2004e4b17023SJohn Marino   tree res;
2005e4b17023SJohn Marino 
2006e4b17023SJohn Marino   res = int_const_binop (code, val1, val2);
2007e4b17023SJohn Marino 
2008e4b17023SJohn Marino   /* If we are using unsigned arithmetic, operate symbolically
2009e4b17023SJohn Marino      on -INF and +INF as int_const_binop only handles signed overflow.  */
2010e4b17023SJohn Marino   if (TYPE_UNSIGNED (TREE_TYPE (val1)))
2011e4b17023SJohn Marino     {
2012e4b17023SJohn Marino       int checkz = compare_values (res, val1);
2013e4b17023SJohn Marino       bool overflow = false;
2014e4b17023SJohn Marino 
2015e4b17023SJohn Marino       /* Ensure that res = val1 [+*] val2 >= val1
2016e4b17023SJohn Marino          or that res = val1 - val2 <= val1.  */
2017e4b17023SJohn Marino       if ((code == PLUS_EXPR
2018e4b17023SJohn Marino 	   && !(checkz == 1 || checkz == 0))
2019e4b17023SJohn Marino           || (code == MINUS_EXPR
2020e4b17023SJohn Marino 	      && !(checkz == 0 || checkz == -1)))
2021e4b17023SJohn Marino 	{
2022e4b17023SJohn Marino 	  overflow = true;
2023e4b17023SJohn Marino 	}
2024e4b17023SJohn Marino       /* Checking for multiplication overflow is done by dividing the
2025e4b17023SJohn Marino 	 output of the multiplication by the first input of the
2026e4b17023SJohn Marino 	 multiplication.  If the result of that division operation is
2027e4b17023SJohn Marino 	 not equal to the second input of the multiplication, then the
2028e4b17023SJohn Marino 	 multiplication overflowed.  */
2029e4b17023SJohn Marino       else if (code == MULT_EXPR && !integer_zerop (val1))
2030e4b17023SJohn Marino 	{
2031e4b17023SJohn Marino 	  tree tmp = int_const_binop (TRUNC_DIV_EXPR,
2032e4b17023SJohn Marino 				      res,
2033e4b17023SJohn Marino 				      val1);
2034e4b17023SJohn Marino 	  int check = compare_values (tmp, val2);
2035e4b17023SJohn Marino 
2036e4b17023SJohn Marino 	  if (check != 0)
2037e4b17023SJohn Marino 	    overflow = true;
2038e4b17023SJohn Marino 	}
2039e4b17023SJohn Marino 
2040e4b17023SJohn Marino       if (overflow)
2041e4b17023SJohn Marino 	{
2042e4b17023SJohn Marino 	  res = copy_node (res);
2043e4b17023SJohn Marino 	  TREE_OVERFLOW (res) = 1;
2044e4b17023SJohn Marino 	}
2045e4b17023SJohn Marino 
2046e4b17023SJohn Marino     }
2047e4b17023SJohn Marino   else if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
2048e4b17023SJohn Marino     /* If the singed operation wraps then int_const_binop has done
2049e4b17023SJohn Marino        everything we want.  */
2050e4b17023SJohn Marino     ;
2051e4b17023SJohn Marino   else if ((TREE_OVERFLOW (res)
2052e4b17023SJohn Marino 	    && !TREE_OVERFLOW (val1)
2053e4b17023SJohn Marino 	    && !TREE_OVERFLOW (val2))
2054e4b17023SJohn Marino 	   || is_overflow_infinity (val1)
2055e4b17023SJohn Marino 	   || is_overflow_infinity (val2))
2056e4b17023SJohn Marino     {
2057e4b17023SJohn Marino       /* If the operation overflowed but neither VAL1 nor VAL2 are
2058e4b17023SJohn Marino 	 overflown, return -INF or +INF depending on the operation
2059e4b17023SJohn Marino 	 and the combination of signs of the operands.  */
2060e4b17023SJohn Marino       int sgn1 = tree_int_cst_sgn (val1);
2061e4b17023SJohn Marino       int sgn2 = tree_int_cst_sgn (val2);
2062e4b17023SJohn Marino 
2063e4b17023SJohn Marino       if (needs_overflow_infinity (TREE_TYPE (res))
2064e4b17023SJohn Marino 	  && !supports_overflow_infinity (TREE_TYPE (res)))
2065e4b17023SJohn Marino 	return NULL_TREE;
2066e4b17023SJohn Marino 
2067e4b17023SJohn Marino       /* We have to punt on adding infinities of different signs,
2068e4b17023SJohn Marino 	 since we can't tell what the sign of the result should be.
2069e4b17023SJohn Marino 	 Likewise for subtracting infinities of the same sign.  */
2070e4b17023SJohn Marino       if (((code == PLUS_EXPR && sgn1 != sgn2)
2071e4b17023SJohn Marino 	   || (code == MINUS_EXPR && sgn1 == sgn2))
2072e4b17023SJohn Marino 	  && is_overflow_infinity (val1)
2073e4b17023SJohn Marino 	  && is_overflow_infinity (val2))
2074e4b17023SJohn Marino 	return NULL_TREE;
2075e4b17023SJohn Marino 
2076e4b17023SJohn Marino       /* Don't try to handle division or shifting of infinities.  */
2077e4b17023SJohn Marino       if ((code == TRUNC_DIV_EXPR
2078e4b17023SJohn Marino 	   || code == FLOOR_DIV_EXPR
2079e4b17023SJohn Marino 	   || code == CEIL_DIV_EXPR
2080e4b17023SJohn Marino 	   || code == EXACT_DIV_EXPR
2081e4b17023SJohn Marino 	   || code == ROUND_DIV_EXPR
2082e4b17023SJohn Marino 	   || code == RSHIFT_EXPR)
2083e4b17023SJohn Marino 	  && (is_overflow_infinity (val1)
2084e4b17023SJohn Marino 	      || is_overflow_infinity (val2)))
2085e4b17023SJohn Marino 	return NULL_TREE;
2086e4b17023SJohn Marino 
2087e4b17023SJohn Marino       /* Notice that we only need to handle the restricted set of
2088e4b17023SJohn Marino 	 operations handled by extract_range_from_binary_expr.
2089e4b17023SJohn Marino 	 Among them, only multiplication, addition and subtraction
2090e4b17023SJohn Marino 	 can yield overflow without overflown operands because we
2091e4b17023SJohn Marino 	 are working with integral types only... except in the
2092e4b17023SJohn Marino 	 case VAL1 = -INF and VAL2 = -1 which overflows to +INF
2093e4b17023SJohn Marino 	 for division too.  */
2094e4b17023SJohn Marino 
2095e4b17023SJohn Marino       /* For multiplication, the sign of the overflow is given
2096e4b17023SJohn Marino 	 by the comparison of the signs of the operands.  */
2097e4b17023SJohn Marino       if ((code == MULT_EXPR && sgn1 == sgn2)
2098e4b17023SJohn Marino           /* For addition, the operands must be of the same sign
2099e4b17023SJohn Marino 	     to yield an overflow.  Its sign is therefore that
2100e4b17023SJohn Marino 	     of one of the operands, for example the first.  For
2101e4b17023SJohn Marino 	     infinite operands X + -INF is negative, not positive.  */
2102e4b17023SJohn Marino 	  || (code == PLUS_EXPR
2103e4b17023SJohn Marino 	      && (sgn1 >= 0
2104e4b17023SJohn Marino 		  ? !is_negative_overflow_infinity (val2)
2105e4b17023SJohn Marino 		  : is_positive_overflow_infinity (val2)))
2106e4b17023SJohn Marino 	  /* For subtraction, non-infinite operands must be of
2107e4b17023SJohn Marino 	     different signs to yield an overflow.  Its sign is
2108e4b17023SJohn Marino 	     therefore that of the first operand or the opposite of
2109e4b17023SJohn Marino 	     that of the second operand.  A first operand of 0 counts
2110e4b17023SJohn Marino 	     as positive here, for the corner case 0 - (-INF), which
2111e4b17023SJohn Marino 	     overflows, but must yield +INF.  For infinite operands 0
2112e4b17023SJohn Marino 	     - INF is negative, not positive.  */
2113e4b17023SJohn Marino 	  || (code == MINUS_EXPR
2114e4b17023SJohn Marino 	      && (sgn1 >= 0
2115e4b17023SJohn Marino 		  ? !is_positive_overflow_infinity (val2)
2116e4b17023SJohn Marino 		  : is_negative_overflow_infinity (val2)))
2117e4b17023SJohn Marino 	  /* We only get in here with positive shift count, so the
2118e4b17023SJohn Marino 	     overflow direction is the same as the sign of val1.
2119e4b17023SJohn Marino 	     Actually rshift does not overflow at all, but we only
2120e4b17023SJohn Marino 	     handle the case of shifting overflowed -INF and +INF.  */
2121e4b17023SJohn Marino 	  || (code == RSHIFT_EXPR
2122e4b17023SJohn Marino 	      && sgn1 >= 0)
2123e4b17023SJohn Marino 	  /* For division, the only case is -INF / -1 = +INF.  */
2124e4b17023SJohn Marino 	  || code == TRUNC_DIV_EXPR
2125e4b17023SJohn Marino 	  || code == FLOOR_DIV_EXPR
2126e4b17023SJohn Marino 	  || code == CEIL_DIV_EXPR
2127e4b17023SJohn Marino 	  || code == EXACT_DIV_EXPR
2128e4b17023SJohn Marino 	  || code == ROUND_DIV_EXPR)
2129e4b17023SJohn Marino 	return (needs_overflow_infinity (TREE_TYPE (res))
2130e4b17023SJohn Marino 		? positive_overflow_infinity (TREE_TYPE (res))
2131e4b17023SJohn Marino 		: TYPE_MAX_VALUE (TREE_TYPE (res)));
2132e4b17023SJohn Marino       else
2133e4b17023SJohn Marino 	return (needs_overflow_infinity (TREE_TYPE (res))
2134e4b17023SJohn Marino 		? negative_overflow_infinity (TREE_TYPE (res))
2135e4b17023SJohn Marino 		: TYPE_MIN_VALUE (TREE_TYPE (res)));
2136e4b17023SJohn Marino     }
2137e4b17023SJohn Marino 
2138e4b17023SJohn Marino   return res;
2139e4b17023SJohn Marino }
2140e4b17023SJohn Marino 
2141e4b17023SJohn Marino 
2142e4b17023SJohn Marino /* For range VR compute two double_int bitmasks.  In *MAY_BE_NONZERO
2143e4b17023SJohn Marino    bitmask if some bit is unset, it means for all numbers in the range
2144e4b17023SJohn Marino    the bit is 0, otherwise it might be 0 or 1.  In *MUST_BE_NONZERO
2145e4b17023SJohn Marino    bitmask if some bit is set, it means for all numbers in the range
2146e4b17023SJohn Marino    the bit is 1, otherwise it might be 0 or 1.  */
2147e4b17023SJohn Marino 
2148e4b17023SJohn Marino static bool
zero_nonzero_bits_from_vr(value_range_t * vr,double_int * may_be_nonzero,double_int * must_be_nonzero)2149e4b17023SJohn Marino zero_nonzero_bits_from_vr (value_range_t *vr,
2150e4b17023SJohn Marino 			   double_int *may_be_nonzero,
2151e4b17023SJohn Marino 			   double_int *must_be_nonzero)
2152e4b17023SJohn Marino {
2153e4b17023SJohn Marino   *may_be_nonzero = double_int_minus_one;
2154e4b17023SJohn Marino   *must_be_nonzero = double_int_zero;
2155e4b17023SJohn Marino   if (!range_int_cst_p (vr))
2156e4b17023SJohn Marino     return false;
2157e4b17023SJohn Marino 
2158e4b17023SJohn Marino   if (range_int_cst_singleton_p (vr))
2159e4b17023SJohn Marino     {
2160e4b17023SJohn Marino       *may_be_nonzero = tree_to_double_int (vr->min);
2161e4b17023SJohn Marino       *must_be_nonzero = *may_be_nonzero;
2162e4b17023SJohn Marino     }
2163e4b17023SJohn Marino   else if (tree_int_cst_sgn (vr->min) >= 0
2164e4b17023SJohn Marino 	   || tree_int_cst_sgn (vr->max) < 0)
2165e4b17023SJohn Marino     {
2166e4b17023SJohn Marino       double_int dmin = tree_to_double_int (vr->min);
2167e4b17023SJohn Marino       double_int dmax = tree_to_double_int (vr->max);
2168e4b17023SJohn Marino       double_int xor_mask = double_int_xor (dmin, dmax);
2169e4b17023SJohn Marino       *may_be_nonzero = double_int_ior (dmin, dmax);
2170e4b17023SJohn Marino       *must_be_nonzero = double_int_and (dmin, dmax);
2171e4b17023SJohn Marino       if (xor_mask.high != 0)
2172e4b17023SJohn Marino 	{
2173e4b17023SJohn Marino 	  unsigned HOST_WIDE_INT mask
2174e4b17023SJohn Marino 	      = ((unsigned HOST_WIDE_INT) 1
2175e4b17023SJohn Marino 		 << floor_log2 (xor_mask.high)) - 1;
2176e4b17023SJohn Marino 	  may_be_nonzero->low = ALL_ONES;
2177e4b17023SJohn Marino 	  may_be_nonzero->high |= mask;
2178e4b17023SJohn Marino 	  must_be_nonzero->low = 0;
2179e4b17023SJohn Marino 	  must_be_nonzero->high &= ~mask;
2180e4b17023SJohn Marino 	}
2181e4b17023SJohn Marino       else if (xor_mask.low != 0)
2182e4b17023SJohn Marino 	{
2183e4b17023SJohn Marino 	  unsigned HOST_WIDE_INT mask
2184e4b17023SJohn Marino 	      = ((unsigned HOST_WIDE_INT) 1
2185e4b17023SJohn Marino 		 << floor_log2 (xor_mask.low)) - 1;
2186e4b17023SJohn Marino 	  may_be_nonzero->low |= mask;
2187e4b17023SJohn Marino 	  must_be_nonzero->low &= ~mask;
2188e4b17023SJohn Marino 	}
2189e4b17023SJohn Marino     }
2190e4b17023SJohn Marino 
2191e4b17023SJohn Marino   return true;
2192e4b17023SJohn Marino }
2193e4b17023SJohn Marino 
2194e4b17023SJohn Marino /* Helper to extract a value-range *VR for a multiplicative operation
2195e4b17023SJohn Marino    *VR0 CODE *VR1.  */
2196e4b17023SJohn Marino 
2197e4b17023SJohn Marino static void
extract_range_from_multiplicative_op_1(value_range_t * vr,enum tree_code code,value_range_t * vr0,value_range_t * vr1)2198e4b17023SJohn Marino extract_range_from_multiplicative_op_1 (value_range_t *vr,
2199e4b17023SJohn Marino 					enum tree_code code,
2200e4b17023SJohn Marino 					value_range_t *vr0, value_range_t *vr1)
2201e4b17023SJohn Marino {
2202e4b17023SJohn Marino   enum value_range_type type;
2203e4b17023SJohn Marino   tree val[4];
2204e4b17023SJohn Marino   size_t i;
2205e4b17023SJohn Marino   tree min, max;
2206e4b17023SJohn Marino   bool sop;
2207e4b17023SJohn Marino   int cmp;
2208e4b17023SJohn Marino 
2209e4b17023SJohn Marino   /* Multiplications, divisions and shifts are a bit tricky to handle,
2210e4b17023SJohn Marino      depending on the mix of signs we have in the two ranges, we
2211e4b17023SJohn Marino      need to operate on different values to get the minimum and
2212e4b17023SJohn Marino      maximum values for the new range.  One approach is to figure
2213e4b17023SJohn Marino      out all the variations of range combinations and do the
2214e4b17023SJohn Marino      operations.
2215e4b17023SJohn Marino 
2216e4b17023SJohn Marino      However, this involves several calls to compare_values and it
2217e4b17023SJohn Marino      is pretty convoluted.  It's simpler to do the 4 operations
2218e4b17023SJohn Marino      (MIN0 OP MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP
2219e4b17023SJohn Marino      MAX1) and then figure the smallest and largest values to form
2220e4b17023SJohn Marino      the new range.  */
2221e4b17023SJohn Marino   gcc_assert (code == MULT_EXPR
2222e4b17023SJohn Marino 	      || code == TRUNC_DIV_EXPR
2223e4b17023SJohn Marino 	      || code == FLOOR_DIV_EXPR
2224e4b17023SJohn Marino 	      || code == CEIL_DIV_EXPR
2225e4b17023SJohn Marino 	      || code == EXACT_DIV_EXPR
2226e4b17023SJohn Marino 	      || code == ROUND_DIV_EXPR
2227e4b17023SJohn Marino 	      || code == RSHIFT_EXPR);
2228e4b17023SJohn Marino   gcc_assert ((vr0->type == VR_RANGE
2229e4b17023SJohn Marino 	       || (code == MULT_EXPR && vr0->type == VR_ANTI_RANGE))
2230e4b17023SJohn Marino 	      && vr0->type == vr1->type);
2231e4b17023SJohn Marino 
2232e4b17023SJohn Marino   type = vr0->type;
2233e4b17023SJohn Marino 
2234e4b17023SJohn Marino   /* Compute the 4 cross operations.  */
2235e4b17023SJohn Marino   sop = false;
2236e4b17023SJohn Marino   val[0] = vrp_int_const_binop (code, vr0->min, vr1->min);
2237e4b17023SJohn Marino   if (val[0] == NULL_TREE)
2238e4b17023SJohn Marino     sop = true;
2239e4b17023SJohn Marino 
2240e4b17023SJohn Marino   if (vr1->max == vr1->min)
2241e4b17023SJohn Marino     val[1] = NULL_TREE;
2242e4b17023SJohn Marino   else
2243e4b17023SJohn Marino     {
2244e4b17023SJohn Marino       val[1] = vrp_int_const_binop (code, vr0->min, vr1->max);
2245e4b17023SJohn Marino       if (val[1] == NULL_TREE)
2246e4b17023SJohn Marino 	sop = true;
2247e4b17023SJohn Marino     }
2248e4b17023SJohn Marino 
2249e4b17023SJohn Marino   if (vr0->max == vr0->min)
2250e4b17023SJohn Marino     val[2] = NULL_TREE;
2251e4b17023SJohn Marino   else
2252e4b17023SJohn Marino     {
2253e4b17023SJohn Marino       val[2] = vrp_int_const_binop (code, vr0->max, vr1->min);
2254e4b17023SJohn Marino       if (val[2] == NULL_TREE)
2255e4b17023SJohn Marino 	sop = true;
2256e4b17023SJohn Marino     }
2257e4b17023SJohn Marino 
2258e4b17023SJohn Marino   if (vr0->min == vr0->max || vr1->min == vr1->max)
2259e4b17023SJohn Marino     val[3] = NULL_TREE;
2260e4b17023SJohn Marino   else
2261e4b17023SJohn Marino     {
2262e4b17023SJohn Marino       val[3] = vrp_int_const_binop (code, vr0->max, vr1->max);
2263e4b17023SJohn Marino       if (val[3] == NULL_TREE)
2264e4b17023SJohn Marino 	sop = true;
2265e4b17023SJohn Marino     }
2266e4b17023SJohn Marino 
2267e4b17023SJohn Marino   if (sop)
2268e4b17023SJohn Marino     {
2269e4b17023SJohn Marino       set_value_range_to_varying (vr);
2270e4b17023SJohn Marino       return;
2271e4b17023SJohn Marino     }
2272e4b17023SJohn Marino 
2273e4b17023SJohn Marino   /* Set MIN to the minimum of VAL[i] and MAX to the maximum
2274e4b17023SJohn Marino      of VAL[i].  */
2275e4b17023SJohn Marino   min = val[0];
2276e4b17023SJohn Marino   max = val[0];
2277e4b17023SJohn Marino   for (i = 1; i < 4; i++)
2278e4b17023SJohn Marino     {
2279e4b17023SJohn Marino       if (!is_gimple_min_invariant (min)
2280e4b17023SJohn Marino 	  || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2281e4b17023SJohn Marino 	  || !is_gimple_min_invariant (max)
2282e4b17023SJohn Marino 	  || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2283e4b17023SJohn Marino 	break;
2284e4b17023SJohn Marino 
2285e4b17023SJohn Marino       if (val[i])
2286e4b17023SJohn Marino 	{
2287e4b17023SJohn Marino 	  if (!is_gimple_min_invariant (val[i])
2288e4b17023SJohn Marino 	      || (TREE_OVERFLOW (val[i])
2289e4b17023SJohn Marino 		  && !is_overflow_infinity (val[i])))
2290e4b17023SJohn Marino 	    {
2291e4b17023SJohn Marino 	      /* If we found an overflowed value, set MIN and MAX
2292e4b17023SJohn Marino 		 to it so that we set the resulting range to
2293e4b17023SJohn Marino 		 VARYING.  */
2294e4b17023SJohn Marino 	      min = max = val[i];
2295e4b17023SJohn Marino 	      break;
2296e4b17023SJohn Marino 	    }
2297e4b17023SJohn Marino 
2298e4b17023SJohn Marino 	  if (compare_values (val[i], min) == -1)
2299e4b17023SJohn Marino 	    min = val[i];
2300e4b17023SJohn Marino 
2301e4b17023SJohn Marino 	  if (compare_values (val[i], max) == 1)
2302e4b17023SJohn Marino 	    max = val[i];
2303e4b17023SJohn Marino 	}
2304e4b17023SJohn Marino     }
2305e4b17023SJohn Marino 
2306e4b17023SJohn Marino   /* If either MIN or MAX overflowed, then set the resulting range to
2307e4b17023SJohn Marino      VARYING.  But we do accept an overflow infinity
2308e4b17023SJohn Marino      representation.  */
2309e4b17023SJohn Marino   if (min == NULL_TREE
2310e4b17023SJohn Marino       || !is_gimple_min_invariant (min)
2311e4b17023SJohn Marino       || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2312e4b17023SJohn Marino       || max == NULL_TREE
2313e4b17023SJohn Marino       || !is_gimple_min_invariant (max)
2314e4b17023SJohn Marino       || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2315e4b17023SJohn Marino     {
2316e4b17023SJohn Marino       set_value_range_to_varying (vr);
2317e4b17023SJohn Marino       return;
2318e4b17023SJohn Marino     }
2319e4b17023SJohn Marino 
2320e4b17023SJohn Marino   /* We punt if:
2321e4b17023SJohn Marino      1) [-INF, +INF]
2322e4b17023SJohn Marino      2) [-INF, +-INF(OVF)]
2323e4b17023SJohn Marino      3) [+-INF(OVF), +INF]
2324e4b17023SJohn Marino      4) [+-INF(OVF), +-INF(OVF)]
2325e4b17023SJohn Marino      We learn nothing when we have INF and INF(OVF) on both sides.
2326e4b17023SJohn Marino      Note that we do accept [-INF, -INF] and [+INF, +INF] without
2327e4b17023SJohn Marino      overflow.  */
2328e4b17023SJohn Marino   if ((vrp_val_is_min (min) || is_overflow_infinity (min))
2329e4b17023SJohn Marino       && (vrp_val_is_max (max) || is_overflow_infinity (max)))
2330e4b17023SJohn Marino     {
2331e4b17023SJohn Marino       set_value_range_to_varying (vr);
2332e4b17023SJohn Marino       return;
2333e4b17023SJohn Marino     }
2334e4b17023SJohn Marino 
2335e4b17023SJohn Marino   cmp = compare_values (min, max);
2336e4b17023SJohn Marino   if (cmp == -2 || cmp == 1)
2337e4b17023SJohn Marino     {
2338e4b17023SJohn Marino       /* If the new range has its limits swapped around (MIN > MAX),
2339e4b17023SJohn Marino 	 then the operation caused one of them to wrap around, mark
2340e4b17023SJohn Marino 	 the new range VARYING.  */
2341e4b17023SJohn Marino       set_value_range_to_varying (vr);
2342e4b17023SJohn Marino     }
2343e4b17023SJohn Marino   else
2344e4b17023SJohn Marino     set_value_range (vr, type, min, max, NULL);
2345e4b17023SJohn Marino }
2346e4b17023SJohn Marino 
2347e4b17023SJohn Marino /* Extract range information from a binary operation CODE based on
2348e4b17023SJohn Marino    the ranges of each of its operands, *VR0 and *VR1 with resulting
2349e4b17023SJohn Marino    type EXPR_TYPE.  The resulting range is stored in *VR.  */
2350e4b17023SJohn Marino 
2351e4b17023SJohn Marino static void
extract_range_from_binary_expr_1(value_range_t * vr,enum tree_code code,tree expr_type,value_range_t * vr0_,value_range_t * vr1_)2352e4b17023SJohn Marino extract_range_from_binary_expr_1 (value_range_t *vr,
2353e4b17023SJohn Marino 				  enum tree_code code, tree expr_type,
2354e4b17023SJohn Marino 				  value_range_t *vr0_, value_range_t *vr1_)
2355e4b17023SJohn Marino {
2356e4b17023SJohn Marino   value_range_t vr0 = *vr0_, vr1 = *vr1_;
2357e4b17023SJohn Marino   enum value_range_type type;
2358e4b17023SJohn Marino   tree min = NULL_TREE, max = NULL_TREE;
2359e4b17023SJohn Marino   int cmp;
2360e4b17023SJohn Marino 
2361e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (expr_type)
2362e4b17023SJohn Marino       && !POINTER_TYPE_P (expr_type))
2363e4b17023SJohn Marino     {
2364e4b17023SJohn Marino       set_value_range_to_varying (vr);
2365e4b17023SJohn Marino       return;
2366e4b17023SJohn Marino     }
2367e4b17023SJohn Marino 
2368e4b17023SJohn Marino   /* Not all binary expressions can be applied to ranges in a
2369e4b17023SJohn Marino      meaningful way.  Handle only arithmetic operations.  */
2370e4b17023SJohn Marino   if (code != PLUS_EXPR
2371e4b17023SJohn Marino       && code != MINUS_EXPR
2372e4b17023SJohn Marino       && code != POINTER_PLUS_EXPR
2373e4b17023SJohn Marino       && code != MULT_EXPR
2374e4b17023SJohn Marino       && code != TRUNC_DIV_EXPR
2375e4b17023SJohn Marino       && code != FLOOR_DIV_EXPR
2376e4b17023SJohn Marino       && code != CEIL_DIV_EXPR
2377e4b17023SJohn Marino       && code != EXACT_DIV_EXPR
2378e4b17023SJohn Marino       && code != ROUND_DIV_EXPR
2379e4b17023SJohn Marino       && code != TRUNC_MOD_EXPR
2380e4b17023SJohn Marino       && code != RSHIFT_EXPR
2381e4b17023SJohn Marino       && code != MIN_EXPR
2382e4b17023SJohn Marino       && code != MAX_EXPR
2383e4b17023SJohn Marino       && code != BIT_AND_EXPR
2384e4b17023SJohn Marino       && code != BIT_IOR_EXPR
2385e4b17023SJohn Marino       && code != BIT_XOR_EXPR)
2386e4b17023SJohn Marino     {
2387e4b17023SJohn Marino       set_value_range_to_varying (vr);
2388e4b17023SJohn Marino       return;
2389e4b17023SJohn Marino     }
2390e4b17023SJohn Marino 
2391e4b17023SJohn Marino   /* If both ranges are UNDEFINED, so is the result.  */
2392e4b17023SJohn Marino   if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED)
2393e4b17023SJohn Marino     {
2394e4b17023SJohn Marino       set_value_range_to_undefined (vr);
2395e4b17023SJohn Marino       return;
2396e4b17023SJohn Marino     }
2397e4b17023SJohn Marino   /* If one of the ranges is UNDEFINED drop it to VARYING for the following
2398e4b17023SJohn Marino      code.  At some point we may want to special-case operations that
2399e4b17023SJohn Marino      have UNDEFINED result for all or some value-ranges of the not UNDEFINED
2400e4b17023SJohn Marino      operand.  */
2401e4b17023SJohn Marino   else if (vr0.type == VR_UNDEFINED)
2402e4b17023SJohn Marino     set_value_range_to_varying (&vr0);
2403e4b17023SJohn Marino   else if (vr1.type == VR_UNDEFINED)
2404e4b17023SJohn Marino     set_value_range_to_varying (&vr1);
2405e4b17023SJohn Marino 
2406e4b17023SJohn Marino   /* The type of the resulting value range defaults to VR0.TYPE.  */
2407e4b17023SJohn Marino   type = vr0.type;
2408e4b17023SJohn Marino 
2409e4b17023SJohn Marino   /* Refuse to operate on VARYING ranges, ranges of different kinds
2410e4b17023SJohn Marino      and symbolic ranges.  As an exception, we allow BIT_AND_EXPR
2411e4b17023SJohn Marino      because we may be able to derive a useful range even if one of
2412e4b17023SJohn Marino      the operands is VR_VARYING or symbolic range.  Similarly for
2413e4b17023SJohn Marino      divisions.  TODO, we may be able to derive anti-ranges in
2414e4b17023SJohn Marino      some cases.  */
2415e4b17023SJohn Marino   if (code != BIT_AND_EXPR
2416e4b17023SJohn Marino       && code != BIT_IOR_EXPR
2417e4b17023SJohn Marino       && code != TRUNC_DIV_EXPR
2418e4b17023SJohn Marino       && code != FLOOR_DIV_EXPR
2419e4b17023SJohn Marino       && code != CEIL_DIV_EXPR
2420e4b17023SJohn Marino       && code != EXACT_DIV_EXPR
2421e4b17023SJohn Marino       && code != ROUND_DIV_EXPR
2422e4b17023SJohn Marino       && code != TRUNC_MOD_EXPR
2423e4b17023SJohn Marino       && (vr0.type == VR_VARYING
2424e4b17023SJohn Marino 	  || vr1.type == VR_VARYING
2425e4b17023SJohn Marino 	  || vr0.type != vr1.type
2426e4b17023SJohn Marino 	  || symbolic_range_p (&vr0)
2427e4b17023SJohn Marino 	  || symbolic_range_p (&vr1)))
2428e4b17023SJohn Marino     {
2429e4b17023SJohn Marino       set_value_range_to_varying (vr);
2430e4b17023SJohn Marino       return;
2431e4b17023SJohn Marino     }
2432e4b17023SJohn Marino 
2433e4b17023SJohn Marino   /* Now evaluate the expression to determine the new range.  */
2434e4b17023SJohn Marino   if (POINTER_TYPE_P (expr_type))
2435e4b17023SJohn Marino     {
2436e4b17023SJohn Marino       if (code == MIN_EXPR || code == MAX_EXPR)
2437e4b17023SJohn Marino 	{
2438e4b17023SJohn Marino 	  /* For MIN/MAX expressions with pointers, we only care about
2439e4b17023SJohn Marino 	     nullness, if both are non null, then the result is nonnull.
2440e4b17023SJohn Marino 	     If both are null, then the result is null. Otherwise they
2441e4b17023SJohn Marino 	     are varying.  */
2442e4b17023SJohn Marino 	  if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
2443e4b17023SJohn Marino 	    set_value_range_to_nonnull (vr, expr_type);
2444e4b17023SJohn Marino 	  else if (range_is_null (&vr0) && range_is_null (&vr1))
2445e4b17023SJohn Marino 	    set_value_range_to_null (vr, expr_type);
2446e4b17023SJohn Marino 	  else
2447e4b17023SJohn Marino 	    set_value_range_to_varying (vr);
2448e4b17023SJohn Marino 	}
2449e4b17023SJohn Marino       else if (code == POINTER_PLUS_EXPR)
2450e4b17023SJohn Marino 	{
2451e4b17023SJohn Marino 	  /* For pointer types, we are really only interested in asserting
2452e4b17023SJohn Marino 	     whether the expression evaluates to non-NULL.  */
2453e4b17023SJohn Marino 	  if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
2454e4b17023SJohn Marino 	    set_value_range_to_nonnull (vr, expr_type);
2455e4b17023SJohn Marino 	  else if (range_is_null (&vr0) && range_is_null (&vr1))
2456e4b17023SJohn Marino 	    set_value_range_to_null (vr, expr_type);
2457e4b17023SJohn Marino 	  else
2458e4b17023SJohn Marino 	    set_value_range_to_varying (vr);
2459e4b17023SJohn Marino 	}
2460e4b17023SJohn Marino       else if (code == BIT_AND_EXPR)
2461e4b17023SJohn Marino 	{
2462e4b17023SJohn Marino 	  /* For pointer types, we are really only interested in asserting
2463e4b17023SJohn Marino 	     whether the expression evaluates to non-NULL.  */
2464e4b17023SJohn Marino 	  if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
2465e4b17023SJohn Marino 	    set_value_range_to_nonnull (vr, expr_type);
2466e4b17023SJohn Marino 	  else if (range_is_null (&vr0) || range_is_null (&vr1))
2467e4b17023SJohn Marino 	    set_value_range_to_null (vr, expr_type);
2468e4b17023SJohn Marino 	  else
2469e4b17023SJohn Marino 	    set_value_range_to_varying (vr);
2470e4b17023SJohn Marino 	}
2471e4b17023SJohn Marino       else
2472e4b17023SJohn Marino 	set_value_range_to_varying (vr);
2473e4b17023SJohn Marino 
2474e4b17023SJohn Marino       return;
2475e4b17023SJohn Marino     }
2476e4b17023SJohn Marino 
2477e4b17023SJohn Marino   /* For integer ranges, apply the operation to each end of the
2478e4b17023SJohn Marino      range and see what we end up with.  */
2479e4b17023SJohn Marino   if (code == PLUS_EXPR)
2480e4b17023SJohn Marino     {
2481e4b17023SJohn Marino       /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
2482e4b17023SJohn Marino 	 VR_VARYING.  It would take more effort to compute a precise
2483e4b17023SJohn Marino 	 range for such a case.  For example, if we have op0 == 1 and
2484e4b17023SJohn Marino 	 op1 == -1 with their ranges both being ~[0,0], we would have
2485e4b17023SJohn Marino 	 op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
2486e4b17023SJohn Marino 	 Note that we are guaranteed to have vr0.type == vr1.type at
2487e4b17023SJohn Marino 	 this point.  */
2488e4b17023SJohn Marino       if (vr0.type == VR_ANTI_RANGE)
2489e4b17023SJohn Marino 	{
2490e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2491e4b17023SJohn Marino 	  return;
2492e4b17023SJohn Marino 	}
2493e4b17023SJohn Marino 
2494e4b17023SJohn Marino       /* For operations that make the resulting range directly
2495e4b17023SJohn Marino 	 proportional to the original ranges, apply the operation to
2496e4b17023SJohn Marino 	 the same end of each range.  */
2497e4b17023SJohn Marino       min = vrp_int_const_binop (code, vr0.min, vr1.min);
2498e4b17023SJohn Marino       max = vrp_int_const_binop (code, vr0.max, vr1.max);
2499e4b17023SJohn Marino 
2500e4b17023SJohn Marino       /* If both additions overflowed the range kind is still correct.
2501e4b17023SJohn Marino 	 This happens regularly with subtracting something in unsigned
2502e4b17023SJohn Marino 	 arithmetic.
2503e4b17023SJohn Marino          ???  See PR30318 for all the cases we do not handle.  */
2504e4b17023SJohn Marino       if ((TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2505e4b17023SJohn Marino 	  && (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2506e4b17023SJohn Marino 	{
2507e4b17023SJohn Marino 	  min = build_int_cst_wide (TREE_TYPE (min),
2508e4b17023SJohn Marino 				    TREE_INT_CST_LOW (min),
2509e4b17023SJohn Marino 				    TREE_INT_CST_HIGH (min));
2510e4b17023SJohn Marino 	  max = build_int_cst_wide (TREE_TYPE (max),
2511e4b17023SJohn Marino 				    TREE_INT_CST_LOW (max),
2512e4b17023SJohn Marino 				    TREE_INT_CST_HIGH (max));
2513e4b17023SJohn Marino 	}
2514e4b17023SJohn Marino     }
2515e4b17023SJohn Marino   else if (code == MIN_EXPR
2516e4b17023SJohn Marino 	   || code == MAX_EXPR)
2517e4b17023SJohn Marino     {
2518e4b17023SJohn Marino       if (vr0.type == VR_ANTI_RANGE)
2519e4b17023SJohn Marino 	{
2520e4b17023SJohn Marino 	  /* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs,
2521e4b17023SJohn Marino 	     the resulting VR_ANTI_RANGE is the same - intersection
2522e4b17023SJohn Marino 	     of the two ranges.  */
2523e4b17023SJohn Marino 	  min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
2524e4b17023SJohn Marino 	  max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max);
2525e4b17023SJohn Marino 	}
2526e4b17023SJohn Marino       else
2527e4b17023SJohn Marino 	{
2528e4b17023SJohn Marino 	  /* For operations that make the resulting range directly
2529e4b17023SJohn Marino 	     proportional to the original ranges, apply the operation to
2530e4b17023SJohn Marino 	     the same end of each range.  */
2531e4b17023SJohn Marino 	  min = vrp_int_const_binop (code, vr0.min, vr1.min);
2532e4b17023SJohn Marino 	  max = vrp_int_const_binop (code, vr0.max, vr1.max);
2533e4b17023SJohn Marino 	}
2534e4b17023SJohn Marino     }
2535e4b17023SJohn Marino   else if (code == MULT_EXPR)
2536e4b17023SJohn Marino     {
2537e4b17023SJohn Marino       /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
2538e4b17023SJohn Marino 	 drop to VR_VARYING.  It would take more effort to compute a
2539e4b17023SJohn Marino 	 precise range for such a case.  For example, if we have
2540e4b17023SJohn Marino 	 op0 == 65536 and op1 == 65536 with their ranges both being
2541e4b17023SJohn Marino 	 ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
2542e4b17023SJohn Marino 	 we cannot claim that the product is in ~[0,0].  Note that we
2543e4b17023SJohn Marino 	 are guaranteed to have vr0.type == vr1.type at this
2544e4b17023SJohn Marino 	 point.  */
2545e4b17023SJohn Marino       if (vr0.type == VR_ANTI_RANGE
2546e4b17023SJohn Marino 	  && !TYPE_OVERFLOW_UNDEFINED (expr_type))
2547e4b17023SJohn Marino 	{
2548e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2549e4b17023SJohn Marino 	  return;
2550e4b17023SJohn Marino 	}
2551e4b17023SJohn Marino 
2552e4b17023SJohn Marino       extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2553e4b17023SJohn Marino       return;
2554e4b17023SJohn Marino     }
2555e4b17023SJohn Marino   else if (code == RSHIFT_EXPR)
2556e4b17023SJohn Marino     {
2557e4b17023SJohn Marino       /* If we have a RSHIFT_EXPR with any shift values outside [0..prec-1],
2558e4b17023SJohn Marino 	 then drop to VR_VARYING.  Outside of this range we get undefined
2559e4b17023SJohn Marino 	 behavior from the shift operation.  We cannot even trust
2560e4b17023SJohn Marino 	 SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl
2561e4b17023SJohn Marino 	 shifts, and the operation at the tree level may be widened.  */
2562e4b17023SJohn Marino       if (vr1.type != VR_RANGE
2563e4b17023SJohn Marino 	  || !value_range_nonnegative_p (&vr1)
2564e4b17023SJohn Marino 	  || TREE_CODE (vr1.max) != INTEGER_CST
2565e4b17023SJohn Marino 	  || compare_tree_int (vr1.max, TYPE_PRECISION (expr_type) - 1) == 1)
2566e4b17023SJohn Marino 	{
2567e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2568e4b17023SJohn Marino 	  return;
2569e4b17023SJohn Marino 	}
2570e4b17023SJohn Marino 
2571e4b17023SJohn Marino       extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2572e4b17023SJohn Marino       return;
2573e4b17023SJohn Marino     }
2574e4b17023SJohn Marino   else if (code == TRUNC_DIV_EXPR
2575e4b17023SJohn Marino 	   || code == FLOOR_DIV_EXPR
2576e4b17023SJohn Marino 	   || code == CEIL_DIV_EXPR
2577e4b17023SJohn Marino 	   || code == EXACT_DIV_EXPR
2578e4b17023SJohn Marino 	   || code == ROUND_DIV_EXPR)
2579e4b17023SJohn Marino     {
2580e4b17023SJohn Marino       if (vr0.type != VR_RANGE || symbolic_range_p (&vr0))
2581e4b17023SJohn Marino 	{
2582e4b17023SJohn Marino 	  /* For division, if op1 has VR_RANGE but op0 does not, something
2583e4b17023SJohn Marino 	     can be deduced just from that range.  Say [min, max] / [4, max]
2584e4b17023SJohn Marino 	     gives [min / 4, max / 4] range.  */
2585e4b17023SJohn Marino 	  if (vr1.type == VR_RANGE
2586e4b17023SJohn Marino 	      && !symbolic_range_p (&vr1)
2587e4b17023SJohn Marino 	      && range_includes_zero_p (vr1.min, vr1.max) == 0)
2588e4b17023SJohn Marino 	    {
2589e4b17023SJohn Marino 	      vr0.type = type = VR_RANGE;
2590e4b17023SJohn Marino 	      vr0.min = vrp_val_min (expr_type);
2591e4b17023SJohn Marino 	      vr0.max = vrp_val_max (expr_type);
2592e4b17023SJohn Marino 	    }
2593e4b17023SJohn Marino 	  else
2594e4b17023SJohn Marino 	    {
2595e4b17023SJohn Marino 	      set_value_range_to_varying (vr);
2596e4b17023SJohn Marino 	      return;
2597e4b17023SJohn Marino 	    }
2598e4b17023SJohn Marino 	}
2599e4b17023SJohn Marino 
2600e4b17023SJohn Marino       /* For divisions, if flag_non_call_exceptions is true, we must
2601e4b17023SJohn Marino 	 not eliminate a division by zero.  */
2602e4b17023SJohn Marino       if (cfun->can_throw_non_call_exceptions
2603e4b17023SJohn Marino 	  && (vr1.type != VR_RANGE
2604e4b17023SJohn Marino 	      || range_includes_zero_p (vr1.min, vr1.max) != 0))
2605e4b17023SJohn Marino 	{
2606e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2607e4b17023SJohn Marino 	  return;
2608e4b17023SJohn Marino 	}
2609e4b17023SJohn Marino 
2610e4b17023SJohn Marino       /* For divisions, if op0 is VR_RANGE, we can deduce a range
2611e4b17023SJohn Marino 	 even if op1 is VR_VARYING, VR_ANTI_RANGE, symbolic or can
2612e4b17023SJohn Marino 	 include 0.  */
2613e4b17023SJohn Marino       if (vr0.type == VR_RANGE
2614e4b17023SJohn Marino 	  && (vr1.type != VR_RANGE
2615e4b17023SJohn Marino 	      || range_includes_zero_p (vr1.min, vr1.max) != 0))
2616e4b17023SJohn Marino 	{
2617e4b17023SJohn Marino 	  tree zero = build_int_cst (TREE_TYPE (vr0.min), 0);
2618e4b17023SJohn Marino 	  int cmp;
2619e4b17023SJohn Marino 
2620e4b17023SJohn Marino 	  min = NULL_TREE;
2621e4b17023SJohn Marino 	  max = NULL_TREE;
2622e4b17023SJohn Marino 	  if (TYPE_UNSIGNED (expr_type)
2623e4b17023SJohn Marino 	      || value_range_nonnegative_p (&vr1))
2624e4b17023SJohn Marino 	    {
2625e4b17023SJohn Marino 	      /* For unsigned division or when divisor is known
2626e4b17023SJohn Marino 		 to be non-negative, the range has to cover
2627e4b17023SJohn Marino 		 all numbers from 0 to max for positive max
2628e4b17023SJohn Marino 		 and all numbers from min to 0 for negative min.  */
2629e4b17023SJohn Marino 	      cmp = compare_values (vr0.max, zero);
2630e4b17023SJohn Marino 	      if (cmp == -1)
2631e4b17023SJohn Marino 		max = zero;
2632e4b17023SJohn Marino 	      else if (cmp == 0 || cmp == 1)
2633e4b17023SJohn Marino 		max = vr0.max;
2634e4b17023SJohn Marino 	      else
2635e4b17023SJohn Marino 		type = VR_VARYING;
2636e4b17023SJohn Marino 	      cmp = compare_values (vr0.min, zero);
2637e4b17023SJohn Marino 	      if (cmp == 1)
2638e4b17023SJohn Marino 		min = zero;
2639e4b17023SJohn Marino 	      else if (cmp == 0 || cmp == -1)
2640e4b17023SJohn Marino 		min = vr0.min;
2641e4b17023SJohn Marino 	      else
2642e4b17023SJohn Marino 		type = VR_VARYING;
2643e4b17023SJohn Marino 	    }
2644e4b17023SJohn Marino 	  else
2645e4b17023SJohn Marino 	    {
2646e4b17023SJohn Marino 	      /* Otherwise the range is -max .. max or min .. -min
2647e4b17023SJohn Marino 		 depending on which bound is bigger in absolute value,
2648e4b17023SJohn Marino 		 as the division can change the sign.  */
2649e4b17023SJohn Marino 	      abs_extent_range (vr, vr0.min, vr0.max);
2650e4b17023SJohn Marino 	      return;
2651e4b17023SJohn Marino 	    }
2652e4b17023SJohn Marino 	  if (type == VR_VARYING)
2653e4b17023SJohn Marino 	    {
2654e4b17023SJohn Marino 	      set_value_range_to_varying (vr);
2655e4b17023SJohn Marino 	      return;
2656e4b17023SJohn Marino 	    }
2657e4b17023SJohn Marino 	}
2658e4b17023SJohn Marino       else
2659e4b17023SJohn Marino 	{
2660e4b17023SJohn Marino 	  extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2661e4b17023SJohn Marino 	  return;
2662e4b17023SJohn Marino 	}
2663e4b17023SJohn Marino     }
2664e4b17023SJohn Marino   else if (code == TRUNC_MOD_EXPR)
2665e4b17023SJohn Marino     {
2666e4b17023SJohn Marino       if (vr1.type != VR_RANGE
2667e4b17023SJohn Marino 	  || range_includes_zero_p (vr1.min, vr1.max) != 0
2668e4b17023SJohn Marino 	  || vrp_val_is_min (vr1.min))
2669e4b17023SJohn Marino 	{
2670e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2671e4b17023SJohn Marino 	  return;
2672e4b17023SJohn Marino 	}
2673e4b17023SJohn Marino       type = VR_RANGE;
2674e4b17023SJohn Marino       /* Compute MAX <|vr1.min|, |vr1.max|> - 1.  */
2675e4b17023SJohn Marino       max = fold_unary_to_constant (ABS_EXPR, expr_type, vr1.min);
2676e4b17023SJohn Marino       if (tree_int_cst_lt (max, vr1.max))
2677e4b17023SJohn Marino 	max = vr1.max;
2678e4b17023SJohn Marino       max = int_const_binop (MINUS_EXPR, max, integer_one_node);
2679e4b17023SJohn Marino       /* If the dividend is non-negative the modulus will be
2680e4b17023SJohn Marino 	 non-negative as well.  */
2681e4b17023SJohn Marino       if (TYPE_UNSIGNED (expr_type)
2682e4b17023SJohn Marino 	  || value_range_nonnegative_p (&vr0))
2683e4b17023SJohn Marino 	min = build_int_cst (TREE_TYPE (max), 0);
2684e4b17023SJohn Marino       else
2685e4b17023SJohn Marino 	min = fold_unary_to_constant (NEGATE_EXPR, expr_type, max);
2686e4b17023SJohn Marino     }
2687e4b17023SJohn Marino   else if (code == MINUS_EXPR)
2688e4b17023SJohn Marino     {
2689e4b17023SJohn Marino       /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
2690e4b17023SJohn Marino 	 VR_VARYING.  It would take more effort to compute a precise
2691e4b17023SJohn Marino 	 range for such a case.  For example, if we have op0 == 1 and
2692e4b17023SJohn Marino 	 op1 == 1 with their ranges both being ~[0,0], we would have
2693e4b17023SJohn Marino 	 op0 - op1 == 0, so we cannot claim that the difference is in
2694e4b17023SJohn Marino 	 ~[0,0].  Note that we are guaranteed to have
2695e4b17023SJohn Marino 	 vr0.type == vr1.type at this point.  */
2696e4b17023SJohn Marino       if (vr0.type == VR_ANTI_RANGE)
2697e4b17023SJohn Marino 	{
2698e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
2699e4b17023SJohn Marino 	  return;
2700e4b17023SJohn Marino 	}
2701e4b17023SJohn Marino 
2702e4b17023SJohn Marino       /* For MINUS_EXPR, apply the operation to the opposite ends of
2703e4b17023SJohn Marino 	 each range.  */
2704e4b17023SJohn Marino       min = vrp_int_const_binop (code, vr0.min, vr1.max);
2705e4b17023SJohn Marino       max = vrp_int_const_binop (code, vr0.max, vr1.min);
2706e4b17023SJohn Marino     }
2707e4b17023SJohn Marino   else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
2708e4b17023SJohn Marino     {
2709e4b17023SJohn Marino       bool int_cst_range0, int_cst_range1;
2710e4b17023SJohn Marino       double_int may_be_nonzero0, may_be_nonzero1;
2711e4b17023SJohn Marino       double_int must_be_nonzero0, must_be_nonzero1;
2712e4b17023SJohn Marino 
2713e4b17023SJohn Marino       int_cst_range0 = zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0,
2714e4b17023SJohn Marino 						  &must_be_nonzero0);
2715e4b17023SJohn Marino       int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1,
2716e4b17023SJohn Marino 						  &must_be_nonzero1);
2717e4b17023SJohn Marino 
2718e4b17023SJohn Marino       type = VR_RANGE;
2719e4b17023SJohn Marino       if (code == BIT_AND_EXPR)
2720e4b17023SJohn Marino 	{
2721e4b17023SJohn Marino 	  double_int dmax;
2722e4b17023SJohn Marino 	  min = double_int_to_tree (expr_type,
2723e4b17023SJohn Marino 				    double_int_and (must_be_nonzero0,
2724e4b17023SJohn Marino 						    must_be_nonzero1));
2725e4b17023SJohn Marino 	  dmax = double_int_and (may_be_nonzero0, may_be_nonzero1);
2726e4b17023SJohn Marino 	  /* If both input ranges contain only negative values we can
2727e4b17023SJohn Marino 	     truncate the result range maximum to the minimum of the
2728e4b17023SJohn Marino 	     input range maxima.  */
2729e4b17023SJohn Marino 	  if (int_cst_range0 && int_cst_range1
2730e4b17023SJohn Marino 	      && tree_int_cst_sgn (vr0.max) < 0
2731e4b17023SJohn Marino 	      && tree_int_cst_sgn (vr1.max) < 0)
2732e4b17023SJohn Marino 	    {
2733e4b17023SJohn Marino 	      dmax = double_int_min (dmax, tree_to_double_int (vr0.max),
2734e4b17023SJohn Marino 				     TYPE_UNSIGNED (expr_type));
2735e4b17023SJohn Marino 	      dmax = double_int_min (dmax, tree_to_double_int (vr1.max),
2736e4b17023SJohn Marino 				     TYPE_UNSIGNED (expr_type));
2737e4b17023SJohn Marino 	    }
2738e4b17023SJohn Marino 	  /* If either input range contains only non-negative values
2739e4b17023SJohn Marino 	     we can truncate the result range maximum to the respective
2740e4b17023SJohn Marino 	     maximum of the input range.  */
2741e4b17023SJohn Marino 	  if (int_cst_range0 && tree_int_cst_sgn (vr0.min) >= 0)
2742e4b17023SJohn Marino 	    dmax = double_int_min (dmax, tree_to_double_int (vr0.max),
2743e4b17023SJohn Marino 				   TYPE_UNSIGNED (expr_type));
2744e4b17023SJohn Marino 	  if (int_cst_range1 && tree_int_cst_sgn (vr1.min) >= 0)
2745e4b17023SJohn Marino 	    dmax = double_int_min (dmax, tree_to_double_int (vr1.max),
2746e4b17023SJohn Marino 				   TYPE_UNSIGNED (expr_type));
2747e4b17023SJohn Marino 	  max = double_int_to_tree (expr_type, dmax);
2748e4b17023SJohn Marino 	}
2749e4b17023SJohn Marino       else if (code == BIT_IOR_EXPR)
2750e4b17023SJohn Marino 	{
2751e4b17023SJohn Marino 	  double_int dmin;
2752e4b17023SJohn Marino 	  max = double_int_to_tree (expr_type,
2753e4b17023SJohn Marino 				    double_int_ior (may_be_nonzero0,
2754e4b17023SJohn Marino 						    may_be_nonzero1));
2755e4b17023SJohn Marino 	  dmin = double_int_ior (must_be_nonzero0, must_be_nonzero1);
2756e4b17023SJohn Marino 	  /* If the input ranges contain only positive values we can
2757e4b17023SJohn Marino 	     truncate the minimum of the result range to the maximum
2758e4b17023SJohn Marino 	     of the input range minima.  */
2759e4b17023SJohn Marino 	  if (int_cst_range0 && int_cst_range1
2760e4b17023SJohn Marino 	      && tree_int_cst_sgn (vr0.min) >= 0
2761e4b17023SJohn Marino 	      && tree_int_cst_sgn (vr1.min) >= 0)
2762e4b17023SJohn Marino 	    {
2763e4b17023SJohn Marino 	      dmin = double_int_max (dmin, tree_to_double_int (vr0.min),
2764e4b17023SJohn Marino 				     TYPE_UNSIGNED (expr_type));
2765e4b17023SJohn Marino 	      dmin = double_int_max (dmin, tree_to_double_int (vr1.min),
2766e4b17023SJohn Marino 				     TYPE_UNSIGNED (expr_type));
2767e4b17023SJohn Marino 	    }
2768e4b17023SJohn Marino 	  /* If either input range contains only negative values
2769e4b17023SJohn Marino 	     we can truncate the minimum of the result range to the
2770e4b17023SJohn Marino 	     respective minimum range.  */
2771e4b17023SJohn Marino 	  if (int_cst_range0 && tree_int_cst_sgn (vr0.max) < 0)
2772e4b17023SJohn Marino 	    dmin = double_int_max (dmin, tree_to_double_int (vr0.min),
2773e4b17023SJohn Marino 				   TYPE_UNSIGNED (expr_type));
2774e4b17023SJohn Marino 	  if (int_cst_range1 && tree_int_cst_sgn (vr1.max) < 0)
2775e4b17023SJohn Marino 	    dmin = double_int_max (dmin, tree_to_double_int (vr1.min),
2776e4b17023SJohn Marino 				   TYPE_UNSIGNED (expr_type));
2777e4b17023SJohn Marino 	  min = double_int_to_tree (expr_type, dmin);
2778e4b17023SJohn Marino 	}
2779e4b17023SJohn Marino       else if (code == BIT_XOR_EXPR)
2780e4b17023SJohn Marino 	{
2781e4b17023SJohn Marino 	  double_int result_zero_bits, result_one_bits;
2782e4b17023SJohn Marino 	  result_zero_bits
2783e4b17023SJohn Marino 	    = double_int_ior (double_int_and (must_be_nonzero0,
2784e4b17023SJohn Marino 					      must_be_nonzero1),
2785e4b17023SJohn Marino 			      double_int_not
2786e4b17023SJohn Marino 			        (double_int_ior (may_be_nonzero0,
2787e4b17023SJohn Marino 						 may_be_nonzero1)));
2788e4b17023SJohn Marino 	  result_one_bits
2789e4b17023SJohn Marino 	    = double_int_ior (double_int_and
2790e4b17023SJohn Marino 			        (must_be_nonzero0,
2791e4b17023SJohn Marino 				 double_int_not (may_be_nonzero1)),
2792e4b17023SJohn Marino 			      double_int_and
2793e4b17023SJohn Marino 			        (must_be_nonzero1,
2794e4b17023SJohn Marino 				 double_int_not (may_be_nonzero0)));
2795e4b17023SJohn Marino 	  max = double_int_to_tree (expr_type,
2796e4b17023SJohn Marino 				    double_int_not (result_zero_bits));
2797e4b17023SJohn Marino 	  min = double_int_to_tree (expr_type, result_one_bits);
2798e4b17023SJohn Marino 	  /* If the range has all positive or all negative values the
2799e4b17023SJohn Marino 	     result is better than VARYING.  */
2800e4b17023SJohn Marino 	  if (tree_int_cst_sgn (min) < 0
2801e4b17023SJohn Marino 	      || tree_int_cst_sgn (max) >= 0)
2802e4b17023SJohn Marino 	    ;
2803e4b17023SJohn Marino 	  else
2804e4b17023SJohn Marino 	    max = min = NULL_TREE;
2805e4b17023SJohn Marino 	}
2806e4b17023SJohn Marino     }
2807e4b17023SJohn Marino   else
2808e4b17023SJohn Marino     gcc_unreachable ();
2809e4b17023SJohn Marino 
2810e4b17023SJohn Marino   /* If either MIN or MAX overflowed, then set the resulting range to
2811e4b17023SJohn Marino      VARYING.  But we do accept an overflow infinity
2812e4b17023SJohn Marino      representation.  */
2813e4b17023SJohn Marino   if (min == NULL_TREE
2814e4b17023SJohn Marino       || !is_gimple_min_invariant (min)
2815e4b17023SJohn Marino       || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2816e4b17023SJohn Marino       || max == NULL_TREE
2817e4b17023SJohn Marino       || !is_gimple_min_invariant (max)
2818e4b17023SJohn Marino       || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2819e4b17023SJohn Marino     {
2820e4b17023SJohn Marino       set_value_range_to_varying (vr);
2821e4b17023SJohn Marino       return;
2822e4b17023SJohn Marino     }
2823e4b17023SJohn Marino 
2824e4b17023SJohn Marino   /* We punt if:
2825e4b17023SJohn Marino      1) [-INF, +INF]
2826e4b17023SJohn Marino      2) [-INF, +-INF(OVF)]
2827e4b17023SJohn Marino      3) [+-INF(OVF), +INF]
2828e4b17023SJohn Marino      4) [+-INF(OVF), +-INF(OVF)]
2829e4b17023SJohn Marino      We learn nothing when we have INF and INF(OVF) on both sides.
2830e4b17023SJohn Marino      Note that we do accept [-INF, -INF] and [+INF, +INF] without
2831e4b17023SJohn Marino      overflow.  */
2832e4b17023SJohn Marino   if ((vrp_val_is_min (min) || is_overflow_infinity (min))
2833e4b17023SJohn Marino       && (vrp_val_is_max (max) || is_overflow_infinity (max)))
2834e4b17023SJohn Marino     {
2835e4b17023SJohn Marino       set_value_range_to_varying (vr);
2836e4b17023SJohn Marino       return;
2837e4b17023SJohn Marino     }
2838e4b17023SJohn Marino 
2839e4b17023SJohn Marino   cmp = compare_values (min, max);
2840e4b17023SJohn Marino   if (cmp == -2 || cmp == 1)
2841e4b17023SJohn Marino     {
2842e4b17023SJohn Marino       /* If the new range has its limits swapped around (MIN > MAX),
2843e4b17023SJohn Marino 	 then the operation caused one of them to wrap around, mark
2844e4b17023SJohn Marino 	 the new range VARYING.  */
2845e4b17023SJohn Marino       set_value_range_to_varying (vr);
2846e4b17023SJohn Marino     }
2847e4b17023SJohn Marino   else
2848e4b17023SJohn Marino     set_value_range (vr, type, min, max, NULL);
2849e4b17023SJohn Marino }
2850e4b17023SJohn Marino 
2851e4b17023SJohn Marino /* Extract range information from a binary expression OP0 CODE OP1 based on
2852e4b17023SJohn Marino    the ranges of each of its operands with resulting type EXPR_TYPE.
2853e4b17023SJohn Marino    The resulting range is stored in *VR.  */
2854e4b17023SJohn Marino 
2855e4b17023SJohn Marino static void
extract_range_from_binary_expr(value_range_t * vr,enum tree_code code,tree expr_type,tree op0,tree op1)2856e4b17023SJohn Marino extract_range_from_binary_expr (value_range_t *vr,
2857e4b17023SJohn Marino 				enum tree_code code,
2858e4b17023SJohn Marino 				tree expr_type, tree op0, tree op1)
2859e4b17023SJohn Marino {
2860e4b17023SJohn Marino   value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2861e4b17023SJohn Marino   value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2862e4b17023SJohn Marino 
2863e4b17023SJohn Marino   /* Get value ranges for each operand.  For constant operands, create
2864e4b17023SJohn Marino      a new value range with the operand to simplify processing.  */
2865e4b17023SJohn Marino   if (TREE_CODE (op0) == SSA_NAME)
2866e4b17023SJohn Marino     vr0 = *(get_value_range (op0));
2867e4b17023SJohn Marino   else if (is_gimple_min_invariant (op0))
2868e4b17023SJohn Marino     set_value_range_to_value (&vr0, op0, NULL);
2869e4b17023SJohn Marino   else
2870e4b17023SJohn Marino     set_value_range_to_varying (&vr0);
2871e4b17023SJohn Marino 
2872e4b17023SJohn Marino   if (TREE_CODE (op1) == SSA_NAME)
2873e4b17023SJohn Marino     vr1 = *(get_value_range (op1));
2874e4b17023SJohn Marino   else if (is_gimple_min_invariant (op1))
2875e4b17023SJohn Marino     set_value_range_to_value (&vr1, op1, NULL);
2876e4b17023SJohn Marino   else
2877e4b17023SJohn Marino     set_value_range_to_varying (&vr1);
2878e4b17023SJohn Marino 
2879e4b17023SJohn Marino   extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
2880e4b17023SJohn Marino }
2881e4b17023SJohn Marino 
2882e4b17023SJohn Marino /* Extract range information from a unary operation CODE based on
2883e4b17023SJohn Marino    the range of its operand *VR0 with type OP0_TYPE with resulting type TYPE.
2884e4b17023SJohn Marino    The The resulting range is stored in *VR.  */
2885e4b17023SJohn Marino 
2886e4b17023SJohn Marino static void
extract_range_from_unary_expr_1(value_range_t * vr,enum tree_code code,tree type,value_range_t * vr0_,tree op0_type)2887e4b17023SJohn Marino extract_range_from_unary_expr_1 (value_range_t *vr,
2888e4b17023SJohn Marino 				 enum tree_code code, tree type,
2889e4b17023SJohn Marino 				 value_range_t *vr0_, tree op0_type)
2890e4b17023SJohn Marino {
2891e4b17023SJohn Marino   value_range_t vr0 = *vr0_;
2892e4b17023SJohn Marino 
2893e4b17023SJohn Marino   /* VRP only operates on integral and pointer types.  */
2894e4b17023SJohn Marino   if (!(INTEGRAL_TYPE_P (op0_type)
2895e4b17023SJohn Marino 	|| POINTER_TYPE_P (op0_type))
2896e4b17023SJohn Marino       || !(INTEGRAL_TYPE_P (type)
2897e4b17023SJohn Marino 	   || POINTER_TYPE_P (type)))
2898e4b17023SJohn Marino     {
2899e4b17023SJohn Marino       set_value_range_to_varying (vr);
2900e4b17023SJohn Marino       return;
2901e4b17023SJohn Marino     }
2902e4b17023SJohn Marino 
2903e4b17023SJohn Marino   /* If VR0 is UNDEFINED, so is the result.  */
2904e4b17023SJohn Marino   if (vr0.type == VR_UNDEFINED)
2905e4b17023SJohn Marino     {
2906e4b17023SJohn Marino       set_value_range_to_undefined (vr);
2907e4b17023SJohn Marino       return;
2908e4b17023SJohn Marino     }
2909e4b17023SJohn Marino 
2910e4b17023SJohn Marino   if (CONVERT_EXPR_CODE_P (code))
2911e4b17023SJohn Marino     {
2912e4b17023SJohn Marino       tree inner_type = op0_type;
2913e4b17023SJohn Marino       tree outer_type = type;
2914e4b17023SJohn Marino 
2915e4b17023SJohn Marino       /* If the expression evaluates to a pointer, we are only interested in
2916e4b17023SJohn Marino 	 determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]).  */
2917e4b17023SJohn Marino       if (POINTER_TYPE_P (type))
2918e4b17023SJohn Marino 	{
2919e4b17023SJohn Marino 	  if (range_is_nonnull (&vr0))
2920e4b17023SJohn Marino 	    set_value_range_to_nonnull (vr, type);
2921e4b17023SJohn Marino 	  else if (range_is_null (&vr0))
2922e4b17023SJohn Marino 	    set_value_range_to_null (vr, type);
2923e4b17023SJohn Marino 	  else
2924e4b17023SJohn Marino 	    set_value_range_to_varying (vr);
2925e4b17023SJohn Marino 	  return;
2926e4b17023SJohn Marino 	}
2927e4b17023SJohn Marino 
2928e4b17023SJohn Marino       /* If VR0 is varying and we increase the type precision, assume
2929e4b17023SJohn Marino 	 a full range for the following transformation.  */
2930e4b17023SJohn Marino       if (vr0.type == VR_VARYING
2931e4b17023SJohn Marino 	  && INTEGRAL_TYPE_P (inner_type)
2932e4b17023SJohn Marino 	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
2933e4b17023SJohn Marino 	{
2934e4b17023SJohn Marino 	  vr0.type = VR_RANGE;
2935e4b17023SJohn Marino 	  vr0.min = TYPE_MIN_VALUE (inner_type);
2936e4b17023SJohn Marino 	  vr0.max = TYPE_MAX_VALUE (inner_type);
2937e4b17023SJohn Marino 	}
2938e4b17023SJohn Marino 
2939e4b17023SJohn Marino       /* If VR0 is a constant range or anti-range and the conversion is
2940e4b17023SJohn Marino 	 not truncating we can convert the min and max values and
2941e4b17023SJohn Marino 	 canonicalize the resulting range.  Otherwise we can do the
2942e4b17023SJohn Marino 	 conversion if the size of the range is less than what the
2943e4b17023SJohn Marino 	 precision of the target type can represent and the range is
2944e4b17023SJohn Marino 	 not an anti-range.  */
2945e4b17023SJohn Marino       if ((vr0.type == VR_RANGE
2946e4b17023SJohn Marino 	   || vr0.type == VR_ANTI_RANGE)
2947e4b17023SJohn Marino 	  && TREE_CODE (vr0.min) == INTEGER_CST
2948e4b17023SJohn Marino 	  && TREE_CODE (vr0.max) == INTEGER_CST
2949e4b17023SJohn Marino 	  && (!is_overflow_infinity (vr0.min)
2950e4b17023SJohn Marino 	      || (vr0.type == VR_RANGE
2951e4b17023SJohn Marino 		  && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
2952e4b17023SJohn Marino 		  && needs_overflow_infinity (outer_type)
2953e4b17023SJohn Marino 		  && supports_overflow_infinity (outer_type)))
2954e4b17023SJohn Marino 	  && (!is_overflow_infinity (vr0.max)
2955e4b17023SJohn Marino 	      || (vr0.type == VR_RANGE
2956e4b17023SJohn Marino 		  && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
2957e4b17023SJohn Marino 		  && needs_overflow_infinity (outer_type)
2958e4b17023SJohn Marino 		  && supports_overflow_infinity (outer_type)))
2959e4b17023SJohn Marino 	  && (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
2960e4b17023SJohn Marino 	      || (vr0.type == VR_RANGE
2961e4b17023SJohn Marino 		  && integer_zerop (int_const_binop (RSHIFT_EXPR,
2962e4b17023SJohn Marino 		       int_const_binop (MINUS_EXPR, vr0.max, vr0.min),
2963e4b17023SJohn Marino 		         size_int (TYPE_PRECISION (outer_type)))))))
2964e4b17023SJohn Marino 	{
2965e4b17023SJohn Marino 	  tree new_min, new_max;
2966e4b17023SJohn Marino 	  if (is_overflow_infinity (vr0.min))
2967e4b17023SJohn Marino 	    new_min = negative_overflow_infinity (outer_type);
2968e4b17023SJohn Marino 	  else
2969e4b17023SJohn Marino 	    new_min = force_fit_type_double (outer_type,
2970e4b17023SJohn Marino 					     tree_to_double_int (vr0.min),
2971e4b17023SJohn Marino 					     0, false);
2972e4b17023SJohn Marino 	  if (is_overflow_infinity (vr0.max))
2973e4b17023SJohn Marino 	    new_max = positive_overflow_infinity (outer_type);
2974e4b17023SJohn Marino 	  else
2975e4b17023SJohn Marino 	    new_max = force_fit_type_double (outer_type,
2976e4b17023SJohn Marino 					     tree_to_double_int (vr0.max),
2977e4b17023SJohn Marino 					     0, false);
2978e4b17023SJohn Marino 	  set_and_canonicalize_value_range (vr, vr0.type,
2979e4b17023SJohn Marino 					    new_min, new_max, NULL);
2980e4b17023SJohn Marino 	  return;
2981e4b17023SJohn Marino 	}
2982e4b17023SJohn Marino 
2983e4b17023SJohn Marino       set_value_range_to_varying (vr);
2984e4b17023SJohn Marino       return;
2985e4b17023SJohn Marino     }
2986e4b17023SJohn Marino   else if (code == NEGATE_EXPR)
2987e4b17023SJohn Marino     {
2988e4b17023SJohn Marino       /* -X is simply 0 - X, so re-use existing code that also handles
2989e4b17023SJohn Marino          anti-ranges fine.  */
2990e4b17023SJohn Marino       value_range_t zero = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2991e4b17023SJohn Marino       set_value_range_to_value (&zero, build_int_cst (type, 0), NULL);
2992e4b17023SJohn Marino       extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0);
2993e4b17023SJohn Marino       return;
2994e4b17023SJohn Marino     }
2995e4b17023SJohn Marino   else if (code == ABS_EXPR)
2996e4b17023SJohn Marino     {
2997e4b17023SJohn Marino       tree min, max;
2998e4b17023SJohn Marino       int cmp;
2999e4b17023SJohn Marino 
3000e4b17023SJohn Marino       /* Pass through vr0 in the easy cases.  */
3001e4b17023SJohn Marino       if (TYPE_UNSIGNED (type)
3002e4b17023SJohn Marino 	  || value_range_nonnegative_p (&vr0))
3003e4b17023SJohn Marino 	{
3004e4b17023SJohn Marino 	  copy_value_range (vr, &vr0);
3005e4b17023SJohn Marino 	  return;
3006e4b17023SJohn Marino 	}
3007e4b17023SJohn Marino 
3008e4b17023SJohn Marino       /* For the remaining varying or symbolic ranges we can't do anything
3009e4b17023SJohn Marino 	 useful.  */
3010e4b17023SJohn Marino       if (vr0.type == VR_VARYING
3011e4b17023SJohn Marino 	  || symbolic_range_p (&vr0))
3012e4b17023SJohn Marino 	{
3013e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
3014e4b17023SJohn Marino 	  return;
3015e4b17023SJohn Marino 	}
3016e4b17023SJohn Marino 
3017e4b17023SJohn Marino       /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
3018e4b17023SJohn Marino          useful range.  */
3019e4b17023SJohn Marino       if (!TYPE_OVERFLOW_UNDEFINED (type)
3020e4b17023SJohn Marino 	  && ((vr0.type == VR_RANGE
3021e4b17023SJohn Marino 	       && vrp_val_is_min (vr0.min))
3022e4b17023SJohn Marino 	      || (vr0.type == VR_ANTI_RANGE
3023e4b17023SJohn Marino 		  && !vrp_val_is_min (vr0.min))))
3024e4b17023SJohn Marino 	{
3025e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
3026e4b17023SJohn Marino 	  return;
3027e4b17023SJohn Marino 	}
3028e4b17023SJohn Marino 
3029e4b17023SJohn Marino       /* ABS_EXPR may flip the range around, if the original range
3030e4b17023SJohn Marino 	 included negative values.  */
3031e4b17023SJohn Marino       if (is_overflow_infinity (vr0.min))
3032e4b17023SJohn Marino 	min = positive_overflow_infinity (type);
3033e4b17023SJohn Marino       else if (!vrp_val_is_min (vr0.min))
3034e4b17023SJohn Marino 	min = fold_unary_to_constant (code, type, vr0.min);
3035e4b17023SJohn Marino       else if (!needs_overflow_infinity (type))
3036e4b17023SJohn Marino 	min = TYPE_MAX_VALUE (type);
3037e4b17023SJohn Marino       else if (supports_overflow_infinity (type))
3038e4b17023SJohn Marino 	min = positive_overflow_infinity (type);
3039e4b17023SJohn Marino       else
3040e4b17023SJohn Marino 	{
3041e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
3042e4b17023SJohn Marino 	  return;
3043e4b17023SJohn Marino 	}
3044e4b17023SJohn Marino 
3045e4b17023SJohn Marino       if (is_overflow_infinity (vr0.max))
3046e4b17023SJohn Marino 	max = positive_overflow_infinity (type);
3047e4b17023SJohn Marino       else if (!vrp_val_is_min (vr0.max))
3048e4b17023SJohn Marino 	max = fold_unary_to_constant (code, type, vr0.max);
3049e4b17023SJohn Marino       else if (!needs_overflow_infinity (type))
3050e4b17023SJohn Marino 	max = TYPE_MAX_VALUE (type);
3051e4b17023SJohn Marino       else if (supports_overflow_infinity (type)
3052e4b17023SJohn Marino 	       /* We shouldn't generate [+INF, +INF] as set_value_range
3053e4b17023SJohn Marino 		  doesn't like this and ICEs.  */
3054e4b17023SJohn Marino 	       && !is_positive_overflow_infinity (min))
3055e4b17023SJohn Marino 	max = positive_overflow_infinity (type);
3056e4b17023SJohn Marino       else
3057e4b17023SJohn Marino 	{
3058e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
3059e4b17023SJohn Marino 	  return;
3060e4b17023SJohn Marino 	}
3061e4b17023SJohn Marino 
3062e4b17023SJohn Marino       cmp = compare_values (min, max);
3063e4b17023SJohn Marino 
3064e4b17023SJohn Marino       /* If a VR_ANTI_RANGEs contains zero, then we have
3065e4b17023SJohn Marino 	 ~[-INF, min(MIN, MAX)].  */
3066e4b17023SJohn Marino       if (vr0.type == VR_ANTI_RANGE)
3067e4b17023SJohn Marino 	{
3068e4b17023SJohn Marino 	  if (range_includes_zero_p (vr0.min, vr0.max) == 1)
3069e4b17023SJohn Marino 	    {
3070e4b17023SJohn Marino 	      /* Take the lower of the two values.  */
3071e4b17023SJohn Marino 	      if (cmp != 1)
3072e4b17023SJohn Marino 		max = min;
3073e4b17023SJohn Marino 
3074e4b17023SJohn Marino 	      /* Create ~[-INF, min (abs(MIN), abs(MAX))]
3075e4b17023SJohn Marino 	         or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
3076e4b17023SJohn Marino 		 flag_wrapv is set and the original anti-range doesn't include
3077e4b17023SJohn Marino 	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
3078e4b17023SJohn Marino 	      if (TYPE_OVERFLOW_WRAPS (type))
3079e4b17023SJohn Marino 		{
3080e4b17023SJohn Marino 		  tree type_min_value = TYPE_MIN_VALUE (type);
3081e4b17023SJohn Marino 
3082e4b17023SJohn Marino 		  min = (vr0.min != type_min_value
3083e4b17023SJohn Marino 			 ? int_const_binop (PLUS_EXPR, type_min_value,
3084e4b17023SJohn Marino 					    integer_one_node)
3085e4b17023SJohn Marino 			 : type_min_value);
3086e4b17023SJohn Marino 		}
3087e4b17023SJohn Marino 	      else
3088e4b17023SJohn Marino 		{
3089e4b17023SJohn Marino 		  if (overflow_infinity_range_p (&vr0))
3090e4b17023SJohn Marino 		    min = negative_overflow_infinity (type);
3091e4b17023SJohn Marino 		  else
3092e4b17023SJohn Marino 		    min = TYPE_MIN_VALUE (type);
3093e4b17023SJohn Marino 		}
3094e4b17023SJohn Marino 	    }
3095e4b17023SJohn Marino 	  else
3096e4b17023SJohn Marino 	    {
3097e4b17023SJohn Marino 	      /* All else has failed, so create the range [0, INF], even for
3098e4b17023SJohn Marino 	         flag_wrapv since TYPE_MIN_VALUE is in the original
3099e4b17023SJohn Marino 	         anti-range.  */
3100e4b17023SJohn Marino 	      vr0.type = VR_RANGE;
3101e4b17023SJohn Marino 	      min = build_int_cst (type, 0);
3102e4b17023SJohn Marino 	      if (needs_overflow_infinity (type))
3103e4b17023SJohn Marino 		{
3104e4b17023SJohn Marino 		  if (supports_overflow_infinity (type))
3105e4b17023SJohn Marino 		    max = positive_overflow_infinity (type);
3106e4b17023SJohn Marino 		  else
3107e4b17023SJohn Marino 		    {
3108e4b17023SJohn Marino 		      set_value_range_to_varying (vr);
3109e4b17023SJohn Marino 		      return;
3110e4b17023SJohn Marino 		    }
3111e4b17023SJohn Marino 		}
3112e4b17023SJohn Marino 	      else
3113e4b17023SJohn Marino 		max = TYPE_MAX_VALUE (type);
3114e4b17023SJohn Marino 	    }
3115e4b17023SJohn Marino 	}
3116e4b17023SJohn Marino 
3117e4b17023SJohn Marino       /* If the range contains zero then we know that the minimum value in the
3118e4b17023SJohn Marino          range will be zero.  */
3119e4b17023SJohn Marino       else if (range_includes_zero_p (vr0.min, vr0.max) == 1)
3120e4b17023SJohn Marino 	{
3121e4b17023SJohn Marino 	  if (cmp == 1)
3122e4b17023SJohn Marino 	    max = min;
3123e4b17023SJohn Marino 	  min = build_int_cst (type, 0);
3124e4b17023SJohn Marino 	}
3125e4b17023SJohn Marino       else
3126e4b17023SJohn Marino 	{
3127e4b17023SJohn Marino           /* If the range was reversed, swap MIN and MAX.  */
3128e4b17023SJohn Marino 	  if (cmp == 1)
3129e4b17023SJohn Marino 	    {
3130e4b17023SJohn Marino 	      tree t = min;
3131e4b17023SJohn Marino 	      min = max;
3132e4b17023SJohn Marino 	      max = t;
3133e4b17023SJohn Marino 	    }
3134e4b17023SJohn Marino 	}
3135e4b17023SJohn Marino 
3136e4b17023SJohn Marino       cmp = compare_values (min, max);
3137e4b17023SJohn Marino       if (cmp == -2 || cmp == 1)
3138e4b17023SJohn Marino 	{
3139e4b17023SJohn Marino 	  /* If the new range has its limits swapped around (MIN > MAX),
3140e4b17023SJohn Marino 	     then the operation caused one of them to wrap around, mark
3141e4b17023SJohn Marino 	     the new range VARYING.  */
3142e4b17023SJohn Marino 	  set_value_range_to_varying (vr);
3143e4b17023SJohn Marino 	}
3144e4b17023SJohn Marino       else
3145e4b17023SJohn Marino 	set_value_range (vr, vr0.type, min, max, NULL);
3146e4b17023SJohn Marino       return;
3147e4b17023SJohn Marino     }
3148e4b17023SJohn Marino   else if (code == BIT_NOT_EXPR)
3149e4b17023SJohn Marino     {
3150e4b17023SJohn Marino       /* ~X is simply -1 - X, so re-use existing code that also handles
3151e4b17023SJohn Marino          anti-ranges fine.  */
3152e4b17023SJohn Marino       value_range_t minusone = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3153e4b17023SJohn Marino       set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
3154e4b17023SJohn Marino       extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
3155e4b17023SJohn Marino 					type, &minusone, &vr0);
3156e4b17023SJohn Marino       return;
3157e4b17023SJohn Marino     }
3158e4b17023SJohn Marino   else if (code == PAREN_EXPR)
3159e4b17023SJohn Marino     {
3160e4b17023SJohn Marino       copy_value_range (vr, &vr0);
3161e4b17023SJohn Marino       return;
3162e4b17023SJohn Marino     }
3163e4b17023SJohn Marino 
3164e4b17023SJohn Marino   /* For unhandled operations fall back to varying.  */
3165e4b17023SJohn Marino   set_value_range_to_varying (vr);
3166e4b17023SJohn Marino   return;
3167e4b17023SJohn Marino }
3168e4b17023SJohn Marino 
3169e4b17023SJohn Marino 
3170e4b17023SJohn Marino /* Extract range information from a unary expression CODE OP0 based on
3171e4b17023SJohn Marino    the range of its operand with resulting type TYPE.
3172e4b17023SJohn Marino    The resulting range is stored in *VR.  */
3173e4b17023SJohn Marino 
3174e4b17023SJohn Marino static void
extract_range_from_unary_expr(value_range_t * vr,enum tree_code code,tree type,tree op0)3175e4b17023SJohn Marino extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
3176e4b17023SJohn Marino 			       tree type, tree op0)
3177e4b17023SJohn Marino {
3178e4b17023SJohn Marino   value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3179e4b17023SJohn Marino 
3180e4b17023SJohn Marino   /* Get value ranges for the operand.  For constant operands, create
3181e4b17023SJohn Marino      a new value range with the operand to simplify processing.  */
3182e4b17023SJohn Marino   if (TREE_CODE (op0) == SSA_NAME)
3183e4b17023SJohn Marino     vr0 = *(get_value_range (op0));
3184e4b17023SJohn Marino   else if (is_gimple_min_invariant (op0))
3185e4b17023SJohn Marino     set_value_range_to_value (&vr0, op0, NULL);
3186e4b17023SJohn Marino   else
3187e4b17023SJohn Marino     set_value_range_to_varying (&vr0);
3188e4b17023SJohn Marino 
3189e4b17023SJohn Marino   extract_range_from_unary_expr_1 (vr, code, type, &vr0, TREE_TYPE (op0));
3190e4b17023SJohn Marino }
3191e4b17023SJohn Marino 
3192e4b17023SJohn Marino 
3193e4b17023SJohn Marino /* Extract range information from a conditional expression STMT based on
3194e4b17023SJohn Marino    the ranges of each of its operands and the expression code.  */
3195e4b17023SJohn Marino 
3196e4b17023SJohn Marino static void
extract_range_from_cond_expr(value_range_t * vr,gimple stmt)3197e4b17023SJohn Marino extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
3198e4b17023SJohn Marino {
3199e4b17023SJohn Marino   tree op0, op1;
3200e4b17023SJohn Marino   value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3201e4b17023SJohn Marino   value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3202e4b17023SJohn Marino 
3203e4b17023SJohn Marino   /* Get value ranges for each operand.  For constant operands, create
3204e4b17023SJohn Marino      a new value range with the operand to simplify processing.  */
3205e4b17023SJohn Marino   op0 = gimple_assign_rhs2 (stmt);
3206e4b17023SJohn Marino   if (TREE_CODE (op0) == SSA_NAME)
3207e4b17023SJohn Marino     vr0 = *(get_value_range (op0));
3208e4b17023SJohn Marino   else if (is_gimple_min_invariant (op0))
3209e4b17023SJohn Marino     set_value_range_to_value (&vr0, op0, NULL);
3210e4b17023SJohn Marino   else
3211e4b17023SJohn Marino     set_value_range_to_varying (&vr0);
3212e4b17023SJohn Marino 
3213e4b17023SJohn Marino   op1 = gimple_assign_rhs3 (stmt);
3214e4b17023SJohn Marino   if (TREE_CODE (op1) == SSA_NAME)
3215e4b17023SJohn Marino     vr1 = *(get_value_range (op1));
3216e4b17023SJohn Marino   else if (is_gimple_min_invariant (op1))
3217e4b17023SJohn Marino     set_value_range_to_value (&vr1, op1, NULL);
3218e4b17023SJohn Marino   else
3219e4b17023SJohn Marino     set_value_range_to_varying (&vr1);
3220e4b17023SJohn Marino 
3221e4b17023SJohn Marino   /* The resulting value range is the union of the operand ranges */
3222e4b17023SJohn Marino   copy_value_range (vr, &vr0);
3223e4b17023SJohn Marino   vrp_meet (vr, &vr1);
3224e4b17023SJohn Marino }
3225e4b17023SJohn Marino 
3226e4b17023SJohn Marino 
3227e4b17023SJohn Marino /* Extract range information from a comparison expression EXPR based
3228e4b17023SJohn Marino    on the range of its operand and the expression code.  */
3229e4b17023SJohn Marino 
3230e4b17023SJohn Marino static void
extract_range_from_comparison(value_range_t * vr,enum tree_code code,tree type,tree op0,tree op1)3231e4b17023SJohn Marino extract_range_from_comparison (value_range_t *vr, enum tree_code code,
3232e4b17023SJohn Marino 			       tree type, tree op0, tree op1)
3233e4b17023SJohn Marino {
3234e4b17023SJohn Marino   bool sop = false;
3235e4b17023SJohn Marino   tree val;
3236e4b17023SJohn Marino 
3237e4b17023SJohn Marino   val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop,
3238e4b17023SJohn Marino   						 NULL);
3239e4b17023SJohn Marino 
3240e4b17023SJohn Marino   /* A disadvantage of using a special infinity as an overflow
3241e4b17023SJohn Marino      representation is that we lose the ability to record overflow
3242e4b17023SJohn Marino      when we don't have an infinity.  So we have to ignore a result
3243e4b17023SJohn Marino      which relies on overflow.  */
3244e4b17023SJohn Marino 
3245e4b17023SJohn Marino   if (val && !is_overflow_infinity (val) && !sop)
3246e4b17023SJohn Marino     {
3247e4b17023SJohn Marino       /* Since this expression was found on the RHS of an assignment,
3248e4b17023SJohn Marino 	 its type may be different from _Bool.  Convert VAL to EXPR's
3249e4b17023SJohn Marino 	 type.  */
3250e4b17023SJohn Marino       val = fold_convert (type, val);
3251e4b17023SJohn Marino       if (is_gimple_min_invariant (val))
3252e4b17023SJohn Marino 	set_value_range_to_value (vr, val, vr->equiv);
3253e4b17023SJohn Marino       else
3254e4b17023SJohn Marino 	set_value_range (vr, VR_RANGE, val, val, vr->equiv);
3255e4b17023SJohn Marino     }
3256e4b17023SJohn Marino   else
3257e4b17023SJohn Marino     /* The result of a comparison is always true or false.  */
3258e4b17023SJohn Marino     set_value_range_to_truthvalue (vr, type);
3259e4b17023SJohn Marino }
3260e4b17023SJohn Marino 
3261e4b17023SJohn Marino /* Try to derive a nonnegative or nonzero range out of STMT relying
3262e4b17023SJohn Marino    primarily on generic routines in fold in conjunction with range data.
3263e4b17023SJohn Marino    Store the result in *VR */
3264e4b17023SJohn Marino 
3265e4b17023SJohn Marino static void
extract_range_basic(value_range_t * vr,gimple stmt)3266e4b17023SJohn Marino extract_range_basic (value_range_t *vr, gimple stmt)
3267e4b17023SJohn Marino {
3268e4b17023SJohn Marino   bool sop = false;
3269e4b17023SJohn Marino   tree type = gimple_expr_type (stmt);
3270e4b17023SJohn Marino 
32715ce9237cSJohn Marino   /* If the call is __builtin_constant_p and the argument is a
32725ce9237cSJohn Marino      function parameter resolve it to false.  This avoids bogus
32735ce9237cSJohn Marino      array bound warnings.
32745ce9237cSJohn Marino      ???  We could do this as early as inlining is finished.  */
32755ce9237cSJohn Marino   if (gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
32765ce9237cSJohn Marino     {
32775ce9237cSJohn Marino       tree arg = gimple_call_arg (stmt, 0);
32785ce9237cSJohn Marino       if (TREE_CODE (arg) == SSA_NAME
32795ce9237cSJohn Marino 	  && SSA_NAME_IS_DEFAULT_DEF (arg)
32805ce9237cSJohn Marino 	  && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
32815ce9237cSJohn Marino 	set_value_range_to_null (vr, type);
32825ce9237cSJohn Marino     }
32835ce9237cSJohn Marino   else if (INTEGRAL_TYPE_P (type)
3284e4b17023SJohn Marino 	   && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
3285e4b17023SJohn Marino     set_value_range_to_nonnegative (vr, type,
3286e4b17023SJohn Marino 				    sop || stmt_overflow_infinity (stmt));
3287e4b17023SJohn Marino   else if (vrp_stmt_computes_nonzero (stmt, &sop)
3288e4b17023SJohn Marino 	   && !sop)
3289e4b17023SJohn Marino     set_value_range_to_nonnull (vr, type);
3290e4b17023SJohn Marino   else
3291e4b17023SJohn Marino     set_value_range_to_varying (vr);
3292e4b17023SJohn Marino }
3293e4b17023SJohn Marino 
3294e4b17023SJohn Marino 
3295e4b17023SJohn Marino /* Try to compute a useful range out of assignment STMT and store it
3296e4b17023SJohn Marino    in *VR.  */
3297e4b17023SJohn Marino 
3298e4b17023SJohn Marino static void
extract_range_from_assignment(value_range_t * vr,gimple stmt)3299e4b17023SJohn Marino extract_range_from_assignment (value_range_t *vr, gimple stmt)
3300e4b17023SJohn Marino {
3301e4b17023SJohn Marino   enum tree_code code = gimple_assign_rhs_code (stmt);
3302e4b17023SJohn Marino 
3303e4b17023SJohn Marino   if (code == ASSERT_EXPR)
3304e4b17023SJohn Marino     extract_range_from_assert (vr, gimple_assign_rhs1 (stmt));
3305e4b17023SJohn Marino   else if (code == SSA_NAME)
3306e4b17023SJohn Marino     extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt));
3307e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_binary)
3308e4b17023SJohn Marino     extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt),
3309e4b17023SJohn Marino 				    gimple_expr_type (stmt),
3310e4b17023SJohn Marino 				    gimple_assign_rhs1 (stmt),
3311e4b17023SJohn Marino 				    gimple_assign_rhs2 (stmt));
3312e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_unary)
3313e4b17023SJohn Marino     extract_range_from_unary_expr (vr, gimple_assign_rhs_code (stmt),
3314e4b17023SJohn Marino 				   gimple_expr_type (stmt),
3315e4b17023SJohn Marino 				   gimple_assign_rhs1 (stmt));
3316e4b17023SJohn Marino   else if (code == COND_EXPR)
3317e4b17023SJohn Marino     extract_range_from_cond_expr (vr, stmt);
3318e4b17023SJohn Marino   else if (TREE_CODE_CLASS (code) == tcc_comparison)
3319e4b17023SJohn Marino     extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
3320e4b17023SJohn Marino 				   gimple_expr_type (stmt),
3321e4b17023SJohn Marino 				   gimple_assign_rhs1 (stmt),
3322e4b17023SJohn Marino 				   gimple_assign_rhs2 (stmt));
3323e4b17023SJohn Marino   else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
3324e4b17023SJohn Marino 	   && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
3325e4b17023SJohn Marino     set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL);
3326e4b17023SJohn Marino   else
3327e4b17023SJohn Marino     set_value_range_to_varying (vr);
3328e4b17023SJohn Marino 
3329e4b17023SJohn Marino   if (vr->type == VR_VARYING)
3330e4b17023SJohn Marino     extract_range_basic (vr, stmt);
3331e4b17023SJohn Marino }
3332e4b17023SJohn Marino 
3333e4b17023SJohn Marino /* Given a range VR, a LOOP and a variable VAR, determine whether it
3334e4b17023SJohn Marino    would be profitable to adjust VR using scalar evolution information
3335e4b17023SJohn Marino    for VAR.  If so, update VR with the new limits.  */
3336e4b17023SJohn Marino 
3337e4b17023SJohn Marino static void
adjust_range_with_scev(value_range_t * vr,struct loop * loop,gimple stmt,tree var)3338e4b17023SJohn Marino adjust_range_with_scev (value_range_t *vr, struct loop *loop,
3339e4b17023SJohn Marino 			gimple stmt, tree var)
3340e4b17023SJohn Marino {
3341e4b17023SJohn Marino   tree init, step, chrec, tmin, tmax, min, max, type, tem;
3342e4b17023SJohn Marino   enum ev_direction dir;
3343e4b17023SJohn Marino 
3344e4b17023SJohn Marino   /* TODO.  Don't adjust anti-ranges.  An anti-range may provide
3345e4b17023SJohn Marino      better opportunities than a regular range, but I'm not sure.  */
3346e4b17023SJohn Marino   if (vr->type == VR_ANTI_RANGE)
3347e4b17023SJohn Marino     return;
3348e4b17023SJohn Marino 
3349e4b17023SJohn Marino   chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
3350e4b17023SJohn Marino 
3351e4b17023SJohn Marino   /* Like in PR19590, scev can return a constant function.  */
3352e4b17023SJohn Marino   if (is_gimple_min_invariant (chrec))
3353e4b17023SJohn Marino     {
3354e4b17023SJohn Marino       set_value_range_to_value (vr, chrec, vr->equiv);
3355e4b17023SJohn Marino       return;
3356e4b17023SJohn Marino     }
3357e4b17023SJohn Marino 
3358e4b17023SJohn Marino   if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
3359e4b17023SJohn Marino     return;
3360e4b17023SJohn Marino 
3361e4b17023SJohn Marino   init = initial_condition_in_loop_num (chrec, loop->num);
3362e4b17023SJohn Marino   tem = op_with_constant_singleton_value_range (init);
3363e4b17023SJohn Marino   if (tem)
3364e4b17023SJohn Marino     init = tem;
3365e4b17023SJohn Marino   step = evolution_part_in_loop_num (chrec, loop->num);
3366e4b17023SJohn Marino   tem = op_with_constant_singleton_value_range (step);
3367e4b17023SJohn Marino   if (tem)
3368e4b17023SJohn Marino     step = tem;
3369e4b17023SJohn Marino 
3370e4b17023SJohn Marino   /* If STEP is symbolic, we can't know whether INIT will be the
3371e4b17023SJohn Marino      minimum or maximum value in the range.  Also, unless INIT is
3372e4b17023SJohn Marino      a simple expression, compare_values and possibly other functions
3373e4b17023SJohn Marino      in tree-vrp won't be able to handle it.  */
3374e4b17023SJohn Marino   if (step == NULL_TREE
3375e4b17023SJohn Marino       || !is_gimple_min_invariant (step)
3376e4b17023SJohn Marino       || !valid_value_p (init))
3377e4b17023SJohn Marino     return;
3378e4b17023SJohn Marino 
3379e4b17023SJohn Marino   dir = scev_direction (chrec);
3380e4b17023SJohn Marino   if (/* Do not adjust ranges if we do not know whether the iv increases
3381e4b17023SJohn Marino 	 or decreases,  ... */
3382e4b17023SJohn Marino       dir == EV_DIR_UNKNOWN
3383e4b17023SJohn Marino       /* ... or if it may wrap.  */
3384e4b17023SJohn Marino       || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
3385e4b17023SJohn Marino 				true))
3386e4b17023SJohn Marino     return;
3387e4b17023SJohn Marino 
3388e4b17023SJohn Marino   /* We use TYPE_MIN_VALUE and TYPE_MAX_VALUE here instead of
3389e4b17023SJohn Marino      negative_overflow_infinity and positive_overflow_infinity,
3390e4b17023SJohn Marino      because we have concluded that the loop probably does not
3391e4b17023SJohn Marino      wrap.  */
3392e4b17023SJohn Marino 
3393e4b17023SJohn Marino   type = TREE_TYPE (var);
3394e4b17023SJohn Marino   if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
3395e4b17023SJohn Marino     tmin = lower_bound_in_type (type, type);
3396e4b17023SJohn Marino   else
3397e4b17023SJohn Marino     tmin = TYPE_MIN_VALUE (type);
3398e4b17023SJohn Marino   if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
3399e4b17023SJohn Marino     tmax = upper_bound_in_type (type, type);
3400e4b17023SJohn Marino   else
3401e4b17023SJohn Marino     tmax = TYPE_MAX_VALUE (type);
3402e4b17023SJohn Marino 
3403e4b17023SJohn Marino   /* Try to use estimated number of iterations for the loop to constrain the
3404e4b17023SJohn Marino      final value in the evolution.  */
3405e4b17023SJohn Marino   if (TREE_CODE (step) == INTEGER_CST
3406e4b17023SJohn Marino       && is_gimple_val (init)
3407e4b17023SJohn Marino       && (TREE_CODE (init) != SSA_NAME
3408e4b17023SJohn Marino 	  || get_value_range (init)->type == VR_RANGE))
3409e4b17023SJohn Marino     {
3410e4b17023SJohn Marino       double_int nit;
3411e4b17023SJohn Marino 
3412e4b17023SJohn Marino       if (estimated_loop_iterations (loop, true, &nit))
3413e4b17023SJohn Marino 	{
3414e4b17023SJohn Marino 	  value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3415e4b17023SJohn Marino 	  double_int dtmp;
3416e4b17023SJohn Marino 	  bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step));
3417e4b17023SJohn Marino 	  int overflow = 0;
3418e4b17023SJohn Marino 
3419e4b17023SJohn Marino 	  dtmp = double_int_mul_with_sign (tree_to_double_int (step), nit,
3420e4b17023SJohn Marino 					   unsigned_p, &overflow);
3421e4b17023SJohn Marino 	  /* If the multiplication overflowed we can't do a meaningful
3422e4b17023SJohn Marino 	     adjustment.  Likewise if the result doesn't fit in the type
3423e4b17023SJohn Marino 	     of the induction variable.  For a signed type we have to
3424e4b17023SJohn Marino 	     check whether the result has the expected signedness which
3425e4b17023SJohn Marino 	     is that of the step as number of iterations is unsigned.  */
3426e4b17023SJohn Marino 	  if (!overflow
3427e4b17023SJohn Marino 	      && double_int_fits_to_tree_p (TREE_TYPE (init), dtmp)
3428e4b17023SJohn Marino 	      && (unsigned_p
3429e4b17023SJohn Marino 		  || ((dtmp.high ^ TREE_INT_CST_HIGH (step)) >= 0)))
3430e4b17023SJohn Marino 	    {
3431e4b17023SJohn Marino 	      tem = double_int_to_tree (TREE_TYPE (init), dtmp);
3432e4b17023SJohn Marino 	      extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
3433e4b17023SJohn Marino 					      TREE_TYPE (init), init, tem);
3434e4b17023SJohn Marino 	      /* Likewise if the addition did.  */
3435e4b17023SJohn Marino 	      if (maxvr.type == VR_RANGE)
3436e4b17023SJohn Marino 		{
3437e4b17023SJohn Marino 		  tmin = maxvr.min;
3438e4b17023SJohn Marino 		  tmax = maxvr.max;
3439e4b17023SJohn Marino 		}
3440e4b17023SJohn Marino 	    }
3441e4b17023SJohn Marino 	}
3442e4b17023SJohn Marino     }
3443e4b17023SJohn Marino 
3444e4b17023SJohn Marino   if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
3445e4b17023SJohn Marino     {
3446e4b17023SJohn Marino       min = tmin;
3447e4b17023SJohn Marino       max = tmax;
3448e4b17023SJohn Marino 
3449e4b17023SJohn Marino       /* For VARYING or UNDEFINED ranges, just about anything we get
3450e4b17023SJohn Marino 	 from scalar evolutions should be better.  */
3451e4b17023SJohn Marino 
3452e4b17023SJohn Marino       if (dir == EV_DIR_DECREASES)
3453e4b17023SJohn Marino 	max = init;
3454e4b17023SJohn Marino       else
3455e4b17023SJohn Marino 	min = init;
3456e4b17023SJohn Marino 
3457e4b17023SJohn Marino       /* If we would create an invalid range, then just assume we
3458e4b17023SJohn Marino 	 know absolutely nothing.  This may be over-conservative,
3459e4b17023SJohn Marino 	 but it's clearly safe, and should happen only in unreachable
3460e4b17023SJohn Marino          parts of code, or for invalid programs.  */
3461e4b17023SJohn Marino       if (compare_values (min, max) == 1)
3462e4b17023SJohn Marino 	return;
3463e4b17023SJohn Marino 
3464e4b17023SJohn Marino       set_value_range (vr, VR_RANGE, min, max, vr->equiv);
3465e4b17023SJohn Marino     }
3466e4b17023SJohn Marino   else if (vr->type == VR_RANGE)
3467e4b17023SJohn Marino     {
3468e4b17023SJohn Marino       min = vr->min;
3469e4b17023SJohn Marino       max = vr->max;
3470e4b17023SJohn Marino 
3471e4b17023SJohn Marino       if (dir == EV_DIR_DECREASES)
3472e4b17023SJohn Marino 	{
3473e4b17023SJohn Marino 	  /* INIT is the maximum value.  If INIT is lower than VR->MAX
3474e4b17023SJohn Marino 	     but no smaller than VR->MIN, set VR->MAX to INIT.  */
3475e4b17023SJohn Marino 	  if (compare_values (init, max) == -1)
3476e4b17023SJohn Marino 	    max = init;
3477e4b17023SJohn Marino 
3478e4b17023SJohn Marino 	  /* According to the loop information, the variable does not
3479e4b17023SJohn Marino 	     overflow.  If we think it does, probably because of an
3480e4b17023SJohn Marino 	     overflow due to arithmetic on a different INF value,
3481e4b17023SJohn Marino 	     reset now.  */
3482e4b17023SJohn Marino 	  if (is_negative_overflow_infinity (min)
3483e4b17023SJohn Marino 	      || compare_values (min, tmin) == -1)
3484e4b17023SJohn Marino 	    min = tmin;
3485e4b17023SJohn Marino 
3486e4b17023SJohn Marino 	}
3487e4b17023SJohn Marino       else
3488e4b17023SJohn Marino 	{
3489e4b17023SJohn Marino 	  /* If INIT is bigger than VR->MIN, set VR->MIN to INIT.  */
3490e4b17023SJohn Marino 	  if (compare_values (init, min) == 1)
3491e4b17023SJohn Marino 	    min = init;
3492e4b17023SJohn Marino 
3493e4b17023SJohn Marino 	  if (is_positive_overflow_infinity (max)
3494e4b17023SJohn Marino 	      || compare_values (tmax, max) == -1)
3495e4b17023SJohn Marino 	    max = tmax;
3496e4b17023SJohn Marino 	}
3497e4b17023SJohn Marino 
3498e4b17023SJohn Marino       /* If we just created an invalid range with the minimum
3499e4b17023SJohn Marino 	 greater than the maximum, we fail conservatively.
3500e4b17023SJohn Marino 	 This should happen only in unreachable
3501e4b17023SJohn Marino 	 parts of code, or for invalid programs.  */
3502e4b17023SJohn Marino       if (compare_values (min, max) == 1)
3503e4b17023SJohn Marino 	return;
3504e4b17023SJohn Marino 
3505e4b17023SJohn Marino       set_value_range (vr, VR_RANGE, min, max, vr->equiv);
3506e4b17023SJohn Marino     }
3507e4b17023SJohn Marino }
3508e4b17023SJohn Marino 
3509e4b17023SJohn Marino /* Return true if VAR may overflow at STMT.  This checks any available
3510e4b17023SJohn Marino    loop information to see if we can determine that VAR does not
3511e4b17023SJohn Marino    overflow.  */
3512e4b17023SJohn Marino 
3513e4b17023SJohn Marino static bool
vrp_var_may_overflow(tree var,gimple stmt)3514e4b17023SJohn Marino vrp_var_may_overflow (tree var, gimple stmt)
3515e4b17023SJohn Marino {
3516e4b17023SJohn Marino   struct loop *l;
3517e4b17023SJohn Marino   tree chrec, init, step;
3518e4b17023SJohn Marino 
3519e4b17023SJohn Marino   if (current_loops == NULL)
3520e4b17023SJohn Marino     return true;
3521e4b17023SJohn Marino 
3522e4b17023SJohn Marino   l = loop_containing_stmt (stmt);
3523e4b17023SJohn Marino   if (l == NULL
3524e4b17023SJohn Marino       || !loop_outer (l))
3525e4b17023SJohn Marino     return true;
3526e4b17023SJohn Marino 
3527e4b17023SJohn Marino   chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
3528e4b17023SJohn Marino   if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
3529e4b17023SJohn Marino     return true;
3530e4b17023SJohn Marino 
3531e4b17023SJohn Marino   init = initial_condition_in_loop_num (chrec, l->num);
3532e4b17023SJohn Marino   step = evolution_part_in_loop_num (chrec, l->num);
3533e4b17023SJohn Marino 
3534e4b17023SJohn Marino   if (step == NULL_TREE
3535e4b17023SJohn Marino       || !is_gimple_min_invariant (step)
3536e4b17023SJohn Marino       || !valid_value_p (init))
3537e4b17023SJohn Marino     return true;
3538e4b17023SJohn Marino 
3539e4b17023SJohn Marino   /* If we get here, we know something useful about VAR based on the
3540e4b17023SJohn Marino      loop information.  If it wraps, it may overflow.  */
3541e4b17023SJohn Marino 
3542e4b17023SJohn Marino   if (scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
3543e4b17023SJohn Marino 			     true))
3544e4b17023SJohn Marino     return true;
3545e4b17023SJohn Marino 
3546e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3547e4b17023SJohn Marino     {
3548e4b17023SJohn Marino       print_generic_expr (dump_file, var, 0);
3549e4b17023SJohn Marino       fprintf (dump_file, ": loop information indicates does not overflow\n");
3550e4b17023SJohn Marino     }
3551e4b17023SJohn Marino 
3552e4b17023SJohn Marino   return false;
3553e4b17023SJohn Marino }
3554e4b17023SJohn Marino 
3555e4b17023SJohn Marino 
3556e4b17023SJohn Marino /* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
3557e4b17023SJohn Marino 
3558e4b17023SJohn Marino    - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
3559e4b17023SJohn Marino      all the values in the ranges.
3560e4b17023SJohn Marino 
3561e4b17023SJohn Marino    - Return BOOLEAN_FALSE_NODE if the comparison always returns false.
3562e4b17023SJohn Marino 
3563e4b17023SJohn Marino    - Return NULL_TREE if it is not always possible to determine the
3564e4b17023SJohn Marino      value of the comparison.
3565e4b17023SJohn Marino 
3566e4b17023SJohn Marino    Also set *STRICT_OVERFLOW_P to indicate whether a range with an
3567e4b17023SJohn Marino    overflow infinity was used in the test.  */
3568e4b17023SJohn Marino 
3569e4b17023SJohn Marino 
3570e4b17023SJohn Marino static tree
compare_ranges(enum tree_code comp,value_range_t * vr0,value_range_t * vr1,bool * strict_overflow_p)3571e4b17023SJohn Marino compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
3572e4b17023SJohn Marino 		bool *strict_overflow_p)
3573e4b17023SJohn Marino {
3574e4b17023SJohn Marino   /* VARYING or UNDEFINED ranges cannot be compared.  */
3575e4b17023SJohn Marino   if (vr0->type == VR_VARYING
3576e4b17023SJohn Marino       || vr0->type == VR_UNDEFINED
3577e4b17023SJohn Marino       || vr1->type == VR_VARYING
3578e4b17023SJohn Marino       || vr1->type == VR_UNDEFINED)
3579e4b17023SJohn Marino     return NULL_TREE;
3580e4b17023SJohn Marino 
3581e4b17023SJohn Marino   /* Anti-ranges need to be handled separately.  */
3582e4b17023SJohn Marino   if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
3583e4b17023SJohn Marino     {
3584e4b17023SJohn Marino       /* If both are anti-ranges, then we cannot compute any
3585e4b17023SJohn Marino 	 comparison.  */
3586e4b17023SJohn Marino       if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
3587e4b17023SJohn Marino 	return NULL_TREE;
3588e4b17023SJohn Marino 
3589e4b17023SJohn Marino       /* These comparisons are never statically computable.  */
3590e4b17023SJohn Marino       if (comp == GT_EXPR
3591e4b17023SJohn Marino 	  || comp == GE_EXPR
3592e4b17023SJohn Marino 	  || comp == LT_EXPR
3593e4b17023SJohn Marino 	  || comp == LE_EXPR)
3594e4b17023SJohn Marino 	return NULL_TREE;
3595e4b17023SJohn Marino 
3596e4b17023SJohn Marino       /* Equality can be computed only between a range and an
3597e4b17023SJohn Marino 	 anti-range.  ~[VAL1, VAL2] == [VAL1, VAL2] is always false.  */
3598e4b17023SJohn Marino       if (vr0->type == VR_RANGE)
3599e4b17023SJohn Marino 	{
3600e4b17023SJohn Marino 	  /* To simplify processing, make VR0 the anti-range.  */
3601e4b17023SJohn Marino 	  value_range_t *tmp = vr0;
3602e4b17023SJohn Marino 	  vr0 = vr1;
3603e4b17023SJohn Marino 	  vr1 = tmp;
3604e4b17023SJohn Marino 	}
3605e4b17023SJohn Marino 
3606e4b17023SJohn Marino       gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
3607e4b17023SJohn Marino 
3608e4b17023SJohn Marino       if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
3609e4b17023SJohn Marino 	  && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
3610e4b17023SJohn Marino 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
3611e4b17023SJohn Marino 
3612e4b17023SJohn Marino       return NULL_TREE;
3613e4b17023SJohn Marino     }
3614e4b17023SJohn Marino 
3615e4b17023SJohn Marino   if (!usable_range_p (vr0, strict_overflow_p)
3616e4b17023SJohn Marino       || !usable_range_p (vr1, strict_overflow_p))
3617e4b17023SJohn Marino     return NULL_TREE;
3618e4b17023SJohn Marino 
3619e4b17023SJohn Marino   /* Simplify processing.  If COMP is GT_EXPR or GE_EXPR, switch the
3620e4b17023SJohn Marino      operands around and change the comparison code.  */
3621e4b17023SJohn Marino   if (comp == GT_EXPR || comp == GE_EXPR)
3622e4b17023SJohn Marino     {
3623e4b17023SJohn Marino       value_range_t *tmp;
3624e4b17023SJohn Marino       comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
3625e4b17023SJohn Marino       tmp = vr0;
3626e4b17023SJohn Marino       vr0 = vr1;
3627e4b17023SJohn Marino       vr1 = tmp;
3628e4b17023SJohn Marino     }
3629e4b17023SJohn Marino 
3630e4b17023SJohn Marino   if (comp == EQ_EXPR)
3631e4b17023SJohn Marino     {
3632e4b17023SJohn Marino       /* Equality may only be computed if both ranges represent
3633e4b17023SJohn Marino 	 exactly one value.  */
3634e4b17023SJohn Marino       if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
3635e4b17023SJohn Marino 	  && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
3636e4b17023SJohn Marino 	{
3637e4b17023SJohn Marino 	  int cmp_min = compare_values_warnv (vr0->min, vr1->min,
3638e4b17023SJohn Marino 					      strict_overflow_p);
3639e4b17023SJohn Marino 	  int cmp_max = compare_values_warnv (vr0->max, vr1->max,
3640e4b17023SJohn Marino 					      strict_overflow_p);
3641e4b17023SJohn Marino 	  if (cmp_min == 0 && cmp_max == 0)
3642e4b17023SJohn Marino 	    return boolean_true_node;
3643e4b17023SJohn Marino 	  else if (cmp_min != -2 && cmp_max != -2)
3644e4b17023SJohn Marino 	    return boolean_false_node;
3645e4b17023SJohn Marino 	}
3646e4b17023SJohn Marino       /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1.  */
3647e4b17023SJohn Marino       else if (compare_values_warnv (vr0->min, vr1->max,
3648e4b17023SJohn Marino 				     strict_overflow_p) == 1
3649e4b17023SJohn Marino 	       || compare_values_warnv (vr1->min, vr0->max,
3650e4b17023SJohn Marino 					strict_overflow_p) == 1)
3651e4b17023SJohn Marino 	return boolean_false_node;
3652e4b17023SJohn Marino 
3653e4b17023SJohn Marino       return NULL_TREE;
3654e4b17023SJohn Marino     }
3655e4b17023SJohn Marino   else if (comp == NE_EXPR)
3656e4b17023SJohn Marino     {
3657e4b17023SJohn Marino       int cmp1, cmp2;
3658e4b17023SJohn Marino 
3659e4b17023SJohn Marino       /* If VR0 is completely to the left or completely to the right
3660e4b17023SJohn Marino 	 of VR1, they are always different.  Notice that we need to
3661e4b17023SJohn Marino 	 make sure that both comparisons yield similar results to
3662e4b17023SJohn Marino 	 avoid comparing values that cannot be compared at
3663e4b17023SJohn Marino 	 compile-time.  */
3664e4b17023SJohn Marino       cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
3665e4b17023SJohn Marino       cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
3666e4b17023SJohn Marino       if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
3667e4b17023SJohn Marino 	return boolean_true_node;
3668e4b17023SJohn Marino 
3669e4b17023SJohn Marino       /* If VR0 and VR1 represent a single value and are identical,
3670e4b17023SJohn Marino 	 return false.  */
3671e4b17023SJohn Marino       else if (compare_values_warnv (vr0->min, vr0->max,
3672e4b17023SJohn Marino 				     strict_overflow_p) == 0
3673e4b17023SJohn Marino 	       && compare_values_warnv (vr1->min, vr1->max,
3674e4b17023SJohn Marino 					strict_overflow_p) == 0
3675e4b17023SJohn Marino 	       && compare_values_warnv (vr0->min, vr1->min,
3676e4b17023SJohn Marino 					strict_overflow_p) == 0
3677e4b17023SJohn Marino 	       && compare_values_warnv (vr0->max, vr1->max,
3678e4b17023SJohn Marino 					strict_overflow_p) == 0)
3679e4b17023SJohn Marino 	return boolean_false_node;
3680e4b17023SJohn Marino 
3681e4b17023SJohn Marino       /* Otherwise, they may or may not be different.  */
3682e4b17023SJohn Marino       else
3683e4b17023SJohn Marino 	return NULL_TREE;
3684e4b17023SJohn Marino     }
3685e4b17023SJohn Marino   else if (comp == LT_EXPR || comp == LE_EXPR)
3686e4b17023SJohn Marino     {
3687e4b17023SJohn Marino       int tst;
3688e4b17023SJohn Marino 
3689e4b17023SJohn Marino       /* If VR0 is to the left of VR1, return true.  */
3690e4b17023SJohn Marino       tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
3691e4b17023SJohn Marino       if ((comp == LT_EXPR && tst == -1)
3692e4b17023SJohn Marino 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
3693e4b17023SJohn Marino 	{
3694e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr0)
3695e4b17023SJohn Marino 	      || overflow_infinity_range_p (vr1))
3696e4b17023SJohn Marino 	    *strict_overflow_p = true;
3697e4b17023SJohn Marino 	  return boolean_true_node;
3698e4b17023SJohn Marino 	}
3699e4b17023SJohn Marino 
3700e4b17023SJohn Marino       /* If VR0 is to the right of VR1, return false.  */
3701e4b17023SJohn Marino       tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
3702e4b17023SJohn Marino       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
3703e4b17023SJohn Marino 	  || (comp == LE_EXPR && tst == 1))
3704e4b17023SJohn Marino 	{
3705e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr0)
3706e4b17023SJohn Marino 	      || overflow_infinity_range_p (vr1))
3707e4b17023SJohn Marino 	    *strict_overflow_p = true;
3708e4b17023SJohn Marino 	  return boolean_false_node;
3709e4b17023SJohn Marino 	}
3710e4b17023SJohn Marino 
3711e4b17023SJohn Marino       /* Otherwise, we don't know.  */
3712e4b17023SJohn Marino       return NULL_TREE;
3713e4b17023SJohn Marino     }
3714e4b17023SJohn Marino 
3715e4b17023SJohn Marino   gcc_unreachable ();
3716e4b17023SJohn Marino }
3717e4b17023SJohn Marino 
3718e4b17023SJohn Marino 
3719e4b17023SJohn Marino /* Given a value range VR, a value VAL and a comparison code COMP, return
3720e4b17023SJohn Marino    BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
3721e4b17023SJohn Marino    values in VR.  Return BOOLEAN_FALSE_NODE if the comparison
3722e4b17023SJohn Marino    always returns false.  Return NULL_TREE if it is not always
3723e4b17023SJohn Marino    possible to determine the value of the comparison.  Also set
3724e4b17023SJohn Marino    *STRICT_OVERFLOW_P to indicate whether a range with an overflow
3725e4b17023SJohn Marino    infinity was used in the test.  */
3726e4b17023SJohn Marino 
3727e4b17023SJohn Marino static tree
compare_range_with_value(enum tree_code comp,value_range_t * vr,tree val,bool * strict_overflow_p)3728e4b17023SJohn Marino compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
3729e4b17023SJohn Marino 			  bool *strict_overflow_p)
3730e4b17023SJohn Marino {
3731e4b17023SJohn Marino   if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
3732e4b17023SJohn Marino     return NULL_TREE;
3733e4b17023SJohn Marino 
3734e4b17023SJohn Marino   /* Anti-ranges need to be handled separately.  */
3735e4b17023SJohn Marino   if (vr->type == VR_ANTI_RANGE)
3736e4b17023SJohn Marino     {
3737e4b17023SJohn Marino       /* For anti-ranges, the only predicates that we can compute at
3738e4b17023SJohn Marino 	 compile time are equality and inequality.  */
3739e4b17023SJohn Marino       if (comp == GT_EXPR
3740e4b17023SJohn Marino 	  || comp == GE_EXPR
3741e4b17023SJohn Marino 	  || comp == LT_EXPR
3742e4b17023SJohn Marino 	  || comp == LE_EXPR)
3743e4b17023SJohn Marino 	return NULL_TREE;
3744e4b17023SJohn Marino 
3745e4b17023SJohn Marino       /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2.  */
3746e4b17023SJohn Marino       if (value_inside_range (val, vr->min, vr->max) == 1)
3747e4b17023SJohn Marino 	return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
3748e4b17023SJohn Marino 
3749e4b17023SJohn Marino       return NULL_TREE;
3750e4b17023SJohn Marino     }
3751e4b17023SJohn Marino 
3752e4b17023SJohn Marino   if (!usable_range_p (vr, strict_overflow_p))
3753e4b17023SJohn Marino     return NULL_TREE;
3754e4b17023SJohn Marino 
3755e4b17023SJohn Marino   if (comp == EQ_EXPR)
3756e4b17023SJohn Marino     {
3757e4b17023SJohn Marino       /* EQ_EXPR may only be computed if VR represents exactly
3758e4b17023SJohn Marino 	 one value.  */
3759e4b17023SJohn Marino       if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
3760e4b17023SJohn Marino 	{
3761e4b17023SJohn Marino 	  int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
3762e4b17023SJohn Marino 	  if (cmp == 0)
3763e4b17023SJohn Marino 	    return boolean_true_node;
3764e4b17023SJohn Marino 	  else if (cmp == -1 || cmp == 1 || cmp == 2)
3765e4b17023SJohn Marino 	    return boolean_false_node;
3766e4b17023SJohn Marino 	}
3767e4b17023SJohn Marino       else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
3768e4b17023SJohn Marino 	       || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
3769e4b17023SJohn Marino 	return boolean_false_node;
3770e4b17023SJohn Marino 
3771e4b17023SJohn Marino       return NULL_TREE;
3772e4b17023SJohn Marino     }
3773e4b17023SJohn Marino   else if (comp == NE_EXPR)
3774e4b17023SJohn Marino     {
3775e4b17023SJohn Marino       /* If VAL is not inside VR, then they are always different.  */
3776e4b17023SJohn Marino       if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
3777e4b17023SJohn Marino 	  || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
3778e4b17023SJohn Marino 	return boolean_true_node;
3779e4b17023SJohn Marino 
3780e4b17023SJohn Marino       /* If VR represents exactly one value equal to VAL, then return
3781e4b17023SJohn Marino 	 false.  */
3782e4b17023SJohn Marino       if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
3783e4b17023SJohn Marino 	  && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
3784e4b17023SJohn Marino 	return boolean_false_node;
3785e4b17023SJohn Marino 
3786e4b17023SJohn Marino       /* Otherwise, they may or may not be different.  */
3787e4b17023SJohn Marino       return NULL_TREE;
3788e4b17023SJohn Marino     }
3789e4b17023SJohn Marino   else if (comp == LT_EXPR || comp == LE_EXPR)
3790e4b17023SJohn Marino     {
3791e4b17023SJohn Marino       int tst;
3792e4b17023SJohn Marino 
3793e4b17023SJohn Marino       /* If VR is to the left of VAL, return true.  */
3794e4b17023SJohn Marino       tst = compare_values_warnv (vr->max, val, strict_overflow_p);
3795e4b17023SJohn Marino       if ((comp == LT_EXPR && tst == -1)
3796e4b17023SJohn Marino 	  || (comp == LE_EXPR && (tst == -1 || tst == 0)))
3797e4b17023SJohn Marino 	{
3798e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr))
3799e4b17023SJohn Marino 	    *strict_overflow_p = true;
3800e4b17023SJohn Marino 	  return boolean_true_node;
3801e4b17023SJohn Marino 	}
3802e4b17023SJohn Marino 
3803e4b17023SJohn Marino       /* If VR is to the right of VAL, return false.  */
3804e4b17023SJohn Marino       tst = compare_values_warnv (vr->min, val, strict_overflow_p);
3805e4b17023SJohn Marino       if ((comp == LT_EXPR && (tst == 0 || tst == 1))
3806e4b17023SJohn Marino 	  || (comp == LE_EXPR && tst == 1))
3807e4b17023SJohn Marino 	{
3808e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr))
3809e4b17023SJohn Marino 	    *strict_overflow_p = true;
3810e4b17023SJohn Marino 	  return boolean_false_node;
3811e4b17023SJohn Marino 	}
3812e4b17023SJohn Marino 
3813e4b17023SJohn Marino       /* Otherwise, we don't know.  */
3814e4b17023SJohn Marino       return NULL_TREE;
3815e4b17023SJohn Marino     }
3816e4b17023SJohn Marino   else if (comp == GT_EXPR || comp == GE_EXPR)
3817e4b17023SJohn Marino     {
3818e4b17023SJohn Marino       int tst;
3819e4b17023SJohn Marino 
3820e4b17023SJohn Marino       /* If VR is to the right of VAL, return true.  */
3821e4b17023SJohn Marino       tst = compare_values_warnv (vr->min, val, strict_overflow_p);
3822e4b17023SJohn Marino       if ((comp == GT_EXPR && tst == 1)
3823e4b17023SJohn Marino 	  || (comp == GE_EXPR && (tst == 0 || tst == 1)))
3824e4b17023SJohn Marino 	{
3825e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr))
3826e4b17023SJohn Marino 	    *strict_overflow_p = true;
3827e4b17023SJohn Marino 	  return boolean_true_node;
3828e4b17023SJohn Marino 	}
3829e4b17023SJohn Marino 
3830e4b17023SJohn Marino       /* If VR is to the left of VAL, return false.  */
3831e4b17023SJohn Marino       tst = compare_values_warnv (vr->max, val, strict_overflow_p);
3832e4b17023SJohn Marino       if ((comp == GT_EXPR && (tst == -1 || tst == 0))
3833e4b17023SJohn Marino 	  || (comp == GE_EXPR && tst == -1))
3834e4b17023SJohn Marino 	{
3835e4b17023SJohn Marino 	  if (overflow_infinity_range_p (vr))
3836e4b17023SJohn Marino 	    *strict_overflow_p = true;
3837e4b17023SJohn Marino 	  return boolean_false_node;
3838e4b17023SJohn Marino 	}
3839e4b17023SJohn Marino 
3840e4b17023SJohn Marino       /* Otherwise, we don't know.  */
3841e4b17023SJohn Marino       return NULL_TREE;
3842e4b17023SJohn Marino     }
3843e4b17023SJohn Marino 
3844e4b17023SJohn Marino   gcc_unreachable ();
3845e4b17023SJohn Marino }
3846e4b17023SJohn Marino 
3847e4b17023SJohn Marino 
3848e4b17023SJohn Marino /* Debugging dumps.  */
3849e4b17023SJohn Marino 
3850e4b17023SJohn Marino void dump_value_range (FILE *, value_range_t *);
3851e4b17023SJohn Marino void debug_value_range (value_range_t *);
3852e4b17023SJohn Marino void dump_all_value_ranges (FILE *);
3853e4b17023SJohn Marino void debug_all_value_ranges (void);
3854e4b17023SJohn Marino void dump_vr_equiv (FILE *, bitmap);
3855e4b17023SJohn Marino void debug_vr_equiv (bitmap);
3856e4b17023SJohn Marino 
3857e4b17023SJohn Marino 
3858e4b17023SJohn Marino /* Dump value range VR to FILE.  */
3859e4b17023SJohn Marino 
3860e4b17023SJohn Marino void
dump_value_range(FILE * file,value_range_t * vr)3861e4b17023SJohn Marino dump_value_range (FILE *file, value_range_t *vr)
3862e4b17023SJohn Marino {
3863e4b17023SJohn Marino   if (vr == NULL)
3864e4b17023SJohn Marino     fprintf (file, "[]");
3865e4b17023SJohn Marino   else if (vr->type == VR_UNDEFINED)
3866e4b17023SJohn Marino     fprintf (file, "UNDEFINED");
3867e4b17023SJohn Marino   else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
3868e4b17023SJohn Marino     {
3869e4b17023SJohn Marino       tree type = TREE_TYPE (vr->min);
3870e4b17023SJohn Marino 
3871e4b17023SJohn Marino       fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
3872e4b17023SJohn Marino 
3873e4b17023SJohn Marino       if (is_negative_overflow_infinity (vr->min))
3874e4b17023SJohn Marino 	fprintf (file, "-INF(OVF)");
3875e4b17023SJohn Marino       else if (INTEGRAL_TYPE_P (type)
3876e4b17023SJohn Marino 	       && !TYPE_UNSIGNED (type)
3877e4b17023SJohn Marino 	       && vrp_val_is_min (vr->min))
3878e4b17023SJohn Marino 	fprintf (file, "-INF");
3879e4b17023SJohn Marino       else
3880e4b17023SJohn Marino 	print_generic_expr (file, vr->min, 0);
3881e4b17023SJohn Marino 
3882e4b17023SJohn Marino       fprintf (file, ", ");
3883e4b17023SJohn Marino 
3884e4b17023SJohn Marino       if (is_positive_overflow_infinity (vr->max))
3885e4b17023SJohn Marino 	fprintf (file, "+INF(OVF)");
3886e4b17023SJohn Marino       else if (INTEGRAL_TYPE_P (type)
3887e4b17023SJohn Marino 	       && vrp_val_is_max (vr->max))
3888e4b17023SJohn Marino 	fprintf (file, "+INF");
3889e4b17023SJohn Marino       else
3890e4b17023SJohn Marino 	print_generic_expr (file, vr->max, 0);
3891e4b17023SJohn Marino 
3892e4b17023SJohn Marino       fprintf (file, "]");
3893e4b17023SJohn Marino 
3894e4b17023SJohn Marino       if (vr->equiv)
3895e4b17023SJohn Marino 	{
3896e4b17023SJohn Marino 	  bitmap_iterator bi;
3897e4b17023SJohn Marino 	  unsigned i, c = 0;
3898e4b17023SJohn Marino 
3899e4b17023SJohn Marino 	  fprintf (file, "  EQUIVALENCES: { ");
3900e4b17023SJohn Marino 
3901e4b17023SJohn Marino 	  EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
3902e4b17023SJohn Marino 	    {
3903e4b17023SJohn Marino 	      print_generic_expr (file, ssa_name (i), 0);
3904e4b17023SJohn Marino 	      fprintf (file, " ");
3905e4b17023SJohn Marino 	      c++;
3906e4b17023SJohn Marino 	    }
3907e4b17023SJohn Marino 
3908e4b17023SJohn Marino 	  fprintf (file, "} (%u elements)", c);
3909e4b17023SJohn Marino 	}
3910e4b17023SJohn Marino     }
3911e4b17023SJohn Marino   else if (vr->type == VR_VARYING)
3912e4b17023SJohn Marino     fprintf (file, "VARYING");
3913e4b17023SJohn Marino   else
3914e4b17023SJohn Marino     fprintf (file, "INVALID RANGE");
3915e4b17023SJohn Marino }
3916e4b17023SJohn Marino 
3917e4b17023SJohn Marino 
3918e4b17023SJohn Marino /* Dump value range VR to stderr.  */
3919e4b17023SJohn Marino 
3920e4b17023SJohn Marino DEBUG_FUNCTION void
debug_value_range(value_range_t * vr)3921e4b17023SJohn Marino debug_value_range (value_range_t *vr)
3922e4b17023SJohn Marino {
3923e4b17023SJohn Marino   dump_value_range (stderr, vr);
3924e4b17023SJohn Marino   fprintf (stderr, "\n");
3925e4b17023SJohn Marino }
3926e4b17023SJohn Marino 
3927e4b17023SJohn Marino 
3928e4b17023SJohn Marino /* Dump value ranges of all SSA_NAMEs to FILE.  */
3929e4b17023SJohn Marino 
3930e4b17023SJohn Marino void
dump_all_value_ranges(FILE * file)3931e4b17023SJohn Marino dump_all_value_ranges (FILE *file)
3932e4b17023SJohn Marino {
3933e4b17023SJohn Marino   size_t i;
3934e4b17023SJohn Marino 
3935e4b17023SJohn Marino   for (i = 0; i < num_vr_values; i++)
3936e4b17023SJohn Marino     {
3937e4b17023SJohn Marino       if (vr_value[i])
3938e4b17023SJohn Marino 	{
3939e4b17023SJohn Marino 	  print_generic_expr (file, ssa_name (i), 0);
3940e4b17023SJohn Marino 	  fprintf (file, ": ");
3941e4b17023SJohn Marino 	  dump_value_range (file, vr_value[i]);
3942e4b17023SJohn Marino 	  fprintf (file, "\n");
3943e4b17023SJohn Marino 	}
3944e4b17023SJohn Marino     }
3945e4b17023SJohn Marino 
3946e4b17023SJohn Marino   fprintf (file, "\n");
3947e4b17023SJohn Marino }
3948e4b17023SJohn Marino 
3949e4b17023SJohn Marino 
3950e4b17023SJohn Marino /* Dump all value ranges to stderr.  */
3951e4b17023SJohn Marino 
3952e4b17023SJohn Marino DEBUG_FUNCTION void
debug_all_value_ranges(void)3953e4b17023SJohn Marino debug_all_value_ranges (void)
3954e4b17023SJohn Marino {
3955e4b17023SJohn Marino   dump_all_value_ranges (stderr);
3956e4b17023SJohn Marino }
3957e4b17023SJohn Marino 
3958e4b17023SJohn Marino 
3959e4b17023SJohn Marino /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
3960e4b17023SJohn Marino    create a new SSA name N and return the assertion assignment
3961e4b17023SJohn Marino    'V = ASSERT_EXPR <V, V OP W>'.  */
3962e4b17023SJohn Marino 
3963e4b17023SJohn Marino static gimple
build_assert_expr_for(tree cond,tree v)3964e4b17023SJohn Marino build_assert_expr_for (tree cond, tree v)
3965e4b17023SJohn Marino {
3966e4b17023SJohn Marino   tree n;
3967e4b17023SJohn Marino   gimple assertion;
3968e4b17023SJohn Marino 
3969e4b17023SJohn Marino   gcc_assert (TREE_CODE (v) == SSA_NAME);
3970e4b17023SJohn Marino   n = duplicate_ssa_name (v, NULL);
3971e4b17023SJohn Marino 
3972e4b17023SJohn Marino   if (COMPARISON_CLASS_P (cond))
3973e4b17023SJohn Marino     {
3974e4b17023SJohn Marino       tree a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
3975e4b17023SJohn Marino       assertion = gimple_build_assign (n, a);
3976e4b17023SJohn Marino     }
3977e4b17023SJohn Marino   else if (TREE_CODE (cond) == SSA_NAME)
3978e4b17023SJohn Marino     {
3979e4b17023SJohn Marino       /* Given V, build the assignment N = true.  */
3980e4b17023SJohn Marino       gcc_assert (v == cond);
3981e4b17023SJohn Marino       assertion = gimple_build_assign (n, boolean_true_node);
3982e4b17023SJohn Marino     }
3983e4b17023SJohn Marino   else
3984e4b17023SJohn Marino     gcc_unreachable ();
3985e4b17023SJohn Marino 
3986e4b17023SJohn Marino   SSA_NAME_DEF_STMT (n) = assertion;
3987e4b17023SJohn Marino 
3988e4b17023SJohn Marino   /* The new ASSERT_EXPR, creates a new SSA name that replaces the
3989e4b17023SJohn Marino      operand of the ASSERT_EXPR. Register the new name and the old one
3990e4b17023SJohn Marino      in the replacement table so that we can fix the SSA web after
3991e4b17023SJohn Marino      adding all the ASSERT_EXPRs.  */
3992e4b17023SJohn Marino   register_new_name_mapping (n, v);
3993e4b17023SJohn Marino 
3994e4b17023SJohn Marino   return assertion;
3995e4b17023SJohn Marino }
3996e4b17023SJohn Marino 
3997e4b17023SJohn Marino 
3998e4b17023SJohn Marino /* Return false if EXPR is a predicate expression involving floating
3999e4b17023SJohn Marino    point values.  */
4000e4b17023SJohn Marino 
4001e4b17023SJohn Marino static inline bool
fp_predicate(gimple stmt)4002e4b17023SJohn Marino fp_predicate (gimple stmt)
4003e4b17023SJohn Marino {
4004e4b17023SJohn Marino   GIMPLE_CHECK (stmt, GIMPLE_COND);
4005e4b17023SJohn Marino 
4006e4b17023SJohn Marino   return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
4007e4b17023SJohn Marino }
4008e4b17023SJohn Marino 
4009e4b17023SJohn Marino 
4010e4b17023SJohn Marino /* If the range of values taken by OP can be inferred after STMT executes,
4011e4b17023SJohn Marino    return the comparison code (COMP_CODE_P) and value (VAL_P) that
4012e4b17023SJohn Marino    describes the inferred range.  Return true if a range could be
4013e4b17023SJohn Marino    inferred.  */
4014e4b17023SJohn Marino 
4015e4b17023SJohn Marino static bool
infer_value_range(gimple stmt,tree op,enum tree_code * comp_code_p,tree * val_p)4016e4b17023SJohn Marino infer_value_range (gimple stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
4017e4b17023SJohn Marino {
4018e4b17023SJohn Marino   *val_p = NULL_TREE;
4019e4b17023SJohn Marino   *comp_code_p = ERROR_MARK;
4020e4b17023SJohn Marino 
4021e4b17023SJohn Marino   /* Do not attempt to infer anything in names that flow through
4022e4b17023SJohn Marino      abnormal edges.  */
4023e4b17023SJohn Marino   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
4024e4b17023SJohn Marino     return false;
4025e4b17023SJohn Marino 
4026e4b17023SJohn Marino   /* Similarly, don't infer anything from statements that may throw
4027e4b17023SJohn Marino      exceptions.  */
4028e4b17023SJohn Marino   if (stmt_could_throw_p (stmt))
4029e4b17023SJohn Marino     return false;
4030e4b17023SJohn Marino 
4031e4b17023SJohn Marino   /* If STMT is the last statement of a basic block with no
4032e4b17023SJohn Marino      successors, there is no point inferring anything about any of its
4033e4b17023SJohn Marino      operands.  We would not be able to find a proper insertion point
4034e4b17023SJohn Marino      for the assertion, anyway.  */
4035e4b17023SJohn Marino   if (stmt_ends_bb_p (stmt) && EDGE_COUNT (gimple_bb (stmt)->succs) == 0)
4036e4b17023SJohn Marino     return false;
4037e4b17023SJohn Marino 
4038e4b17023SJohn Marino   /* We can only assume that a pointer dereference will yield
4039e4b17023SJohn Marino      non-NULL if -fdelete-null-pointer-checks is enabled.  */
4040e4b17023SJohn Marino   if (flag_delete_null_pointer_checks
4041e4b17023SJohn Marino       && POINTER_TYPE_P (TREE_TYPE (op))
4042e4b17023SJohn Marino       && gimple_code (stmt) != GIMPLE_ASM)
4043e4b17023SJohn Marino     {
4044e4b17023SJohn Marino       unsigned num_uses, num_loads, num_stores;
4045e4b17023SJohn Marino 
4046e4b17023SJohn Marino       count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores);
4047e4b17023SJohn Marino       if (num_loads + num_stores > 0)
4048e4b17023SJohn Marino 	{
4049e4b17023SJohn Marino 	  *val_p = build_int_cst (TREE_TYPE (op), 0);
4050e4b17023SJohn Marino 	  *comp_code_p = NE_EXPR;
4051e4b17023SJohn Marino 	  return true;
4052e4b17023SJohn Marino 	}
4053e4b17023SJohn Marino     }
4054e4b17023SJohn Marino 
4055e4b17023SJohn Marino   return false;
4056e4b17023SJohn Marino }
4057e4b17023SJohn Marino 
4058e4b17023SJohn Marino 
4059e4b17023SJohn Marino void dump_asserts_for (FILE *, tree);
4060e4b17023SJohn Marino void debug_asserts_for (tree);
4061e4b17023SJohn Marino void dump_all_asserts (FILE *);
4062e4b17023SJohn Marino void debug_all_asserts (void);
4063e4b17023SJohn Marino 
4064e4b17023SJohn Marino /* Dump all the registered assertions for NAME to FILE.  */
4065e4b17023SJohn Marino 
4066e4b17023SJohn Marino void
dump_asserts_for(FILE * file,tree name)4067e4b17023SJohn Marino dump_asserts_for (FILE *file, tree name)
4068e4b17023SJohn Marino {
4069e4b17023SJohn Marino   assert_locus_t loc;
4070e4b17023SJohn Marino 
4071e4b17023SJohn Marino   fprintf (file, "Assertions to be inserted for ");
4072e4b17023SJohn Marino   print_generic_expr (file, name, 0);
4073e4b17023SJohn Marino   fprintf (file, "\n");
4074e4b17023SJohn Marino 
4075e4b17023SJohn Marino   loc = asserts_for[SSA_NAME_VERSION (name)];
4076e4b17023SJohn Marino   while (loc)
4077e4b17023SJohn Marino     {
4078e4b17023SJohn Marino       fprintf (file, "\t");
4079e4b17023SJohn Marino       print_gimple_stmt (file, gsi_stmt (loc->si), 0, 0);
4080e4b17023SJohn Marino       fprintf (file, "\n\tBB #%d", loc->bb->index);
4081e4b17023SJohn Marino       if (loc->e)
4082e4b17023SJohn Marino 	{
4083e4b17023SJohn Marino 	  fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
4084e4b17023SJohn Marino 	           loc->e->dest->index);
4085e4b17023SJohn Marino 	  dump_edge_info (file, loc->e, 0);
4086e4b17023SJohn Marino 	}
4087e4b17023SJohn Marino       fprintf (file, "\n\tPREDICATE: ");
4088e4b17023SJohn Marino       print_generic_expr (file, name, 0);
4089e4b17023SJohn Marino       fprintf (file, " %s ", tree_code_name[(int)loc->comp_code]);
4090e4b17023SJohn Marino       print_generic_expr (file, loc->val, 0);
4091e4b17023SJohn Marino       fprintf (file, "\n\n");
4092e4b17023SJohn Marino       loc = loc->next;
4093e4b17023SJohn Marino     }
4094e4b17023SJohn Marino 
4095e4b17023SJohn Marino   fprintf (file, "\n");
4096e4b17023SJohn Marino }
4097e4b17023SJohn Marino 
4098e4b17023SJohn Marino 
4099e4b17023SJohn Marino /* Dump all the registered assertions for NAME to stderr.  */
4100e4b17023SJohn Marino 
4101e4b17023SJohn Marino DEBUG_FUNCTION void
debug_asserts_for(tree name)4102e4b17023SJohn Marino debug_asserts_for (tree name)
4103e4b17023SJohn Marino {
4104e4b17023SJohn Marino   dump_asserts_for (stderr, name);
4105e4b17023SJohn Marino }
4106e4b17023SJohn Marino 
4107e4b17023SJohn Marino 
4108e4b17023SJohn Marino /* Dump all the registered assertions for all the names to FILE.  */
4109e4b17023SJohn Marino 
4110e4b17023SJohn Marino void
dump_all_asserts(FILE * file)4111e4b17023SJohn Marino dump_all_asserts (FILE *file)
4112e4b17023SJohn Marino {
4113e4b17023SJohn Marino   unsigned i;
4114e4b17023SJohn Marino   bitmap_iterator bi;
4115e4b17023SJohn Marino 
4116e4b17023SJohn Marino   fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
4117e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
4118e4b17023SJohn Marino     dump_asserts_for (file, ssa_name (i));
4119e4b17023SJohn Marino   fprintf (file, "\n");
4120e4b17023SJohn Marino }
4121e4b17023SJohn Marino 
4122e4b17023SJohn Marino 
4123e4b17023SJohn Marino /* Dump all the registered assertions for all the names to stderr.  */
4124e4b17023SJohn Marino 
4125e4b17023SJohn Marino DEBUG_FUNCTION void
debug_all_asserts(void)4126e4b17023SJohn Marino debug_all_asserts (void)
4127e4b17023SJohn Marino {
4128e4b17023SJohn Marino   dump_all_asserts (stderr);
4129e4b17023SJohn Marino }
4130e4b17023SJohn Marino 
4131e4b17023SJohn Marino 
4132e4b17023SJohn Marino /* If NAME doesn't have an ASSERT_EXPR registered for asserting
4133e4b17023SJohn Marino    'EXPR COMP_CODE VAL' at a location that dominates block BB or
4134e4b17023SJohn Marino    E->DEST, then register this location as a possible insertion point
4135e4b17023SJohn Marino    for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
4136e4b17023SJohn Marino 
4137e4b17023SJohn Marino    BB, E and SI provide the exact insertion point for the new
4138e4b17023SJohn Marino    ASSERT_EXPR.  If BB is NULL, then the ASSERT_EXPR is to be inserted
4139e4b17023SJohn Marino    on edge E.  Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
4140e4b17023SJohn Marino    BB.  If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
4141e4b17023SJohn Marino    must not be NULL.  */
4142e4b17023SJohn Marino 
4143e4b17023SJohn Marino static void
register_new_assert_for(tree name,tree expr,enum tree_code comp_code,tree val,basic_block bb,edge e,gimple_stmt_iterator si)4144e4b17023SJohn Marino register_new_assert_for (tree name, tree expr,
4145e4b17023SJohn Marino 			 enum tree_code comp_code,
4146e4b17023SJohn Marino 			 tree val,
4147e4b17023SJohn Marino 			 basic_block bb,
4148e4b17023SJohn Marino 			 edge e,
4149e4b17023SJohn Marino 			 gimple_stmt_iterator si)
4150e4b17023SJohn Marino {
4151e4b17023SJohn Marino   assert_locus_t n, loc, last_loc;
4152e4b17023SJohn Marino   basic_block dest_bb;
4153e4b17023SJohn Marino 
4154e4b17023SJohn Marino   gcc_checking_assert (bb == NULL || e == NULL);
4155e4b17023SJohn Marino 
4156e4b17023SJohn Marino   if (e == NULL)
4157e4b17023SJohn Marino     gcc_checking_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
4158e4b17023SJohn Marino 			 && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
4159e4b17023SJohn Marino 
4160e4b17023SJohn Marino   /* Never build an assert comparing against an integer constant with
4161e4b17023SJohn Marino      TREE_OVERFLOW set.  This confuses our undefined overflow warning
4162e4b17023SJohn Marino      machinery.  */
4163e4b17023SJohn Marino   if (TREE_CODE (val) == INTEGER_CST
4164e4b17023SJohn Marino       && TREE_OVERFLOW (val))
4165e4b17023SJohn Marino     val = build_int_cst_wide (TREE_TYPE (val),
4166e4b17023SJohn Marino 			      TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val));
4167e4b17023SJohn Marino 
4168e4b17023SJohn Marino   /* The new assertion A will be inserted at BB or E.  We need to
4169e4b17023SJohn Marino      determine if the new location is dominated by a previously
4170e4b17023SJohn Marino      registered location for A.  If we are doing an edge insertion,
4171e4b17023SJohn Marino      assume that A will be inserted at E->DEST.  Note that this is not
4172e4b17023SJohn Marino      necessarily true.
4173e4b17023SJohn Marino 
4174e4b17023SJohn Marino      If E is a critical edge, it will be split.  But even if E is
4175e4b17023SJohn Marino      split, the new block will dominate the same set of blocks that
4176e4b17023SJohn Marino      E->DEST dominates.
4177e4b17023SJohn Marino 
4178e4b17023SJohn Marino      The reverse, however, is not true, blocks dominated by E->DEST
4179e4b17023SJohn Marino      will not be dominated by the new block created to split E.  So,
4180e4b17023SJohn Marino      if the insertion location is on a critical edge, we will not use
4181e4b17023SJohn Marino      the new location to move another assertion previously registered
4182e4b17023SJohn Marino      at a block dominated by E->DEST.  */
4183e4b17023SJohn Marino   dest_bb = (bb) ? bb : e->dest;
4184e4b17023SJohn Marino 
4185e4b17023SJohn Marino   /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
4186e4b17023SJohn Marino      VAL at a block dominating DEST_BB, then we don't need to insert a new
4187e4b17023SJohn Marino      one.  Similarly, if the same assertion already exists at a block
4188e4b17023SJohn Marino      dominated by DEST_BB and the new location is not on a critical
4189e4b17023SJohn Marino      edge, then update the existing location for the assertion (i.e.,
4190e4b17023SJohn Marino      move the assertion up in the dominance tree).
4191e4b17023SJohn Marino 
4192e4b17023SJohn Marino      Note, this is implemented as a simple linked list because there
4193e4b17023SJohn Marino      should not be more than a handful of assertions registered per
4194e4b17023SJohn Marino      name.  If this becomes a performance problem, a table hashed by
4195e4b17023SJohn Marino      COMP_CODE and VAL could be implemented.  */
4196e4b17023SJohn Marino   loc = asserts_for[SSA_NAME_VERSION (name)];
4197e4b17023SJohn Marino   last_loc = loc;
4198e4b17023SJohn Marino   while (loc)
4199e4b17023SJohn Marino     {
4200e4b17023SJohn Marino       if (loc->comp_code == comp_code
4201e4b17023SJohn Marino 	  && (loc->val == val
4202e4b17023SJohn Marino 	      || operand_equal_p (loc->val, val, 0))
4203e4b17023SJohn Marino 	  && (loc->expr == expr
4204e4b17023SJohn Marino 	      || operand_equal_p (loc->expr, expr, 0)))
4205e4b17023SJohn Marino 	{
4206e4b17023SJohn Marino 	  /* If the assertion NAME COMP_CODE VAL has already been
4207e4b17023SJohn Marino 	     registered at a basic block that dominates DEST_BB, then
4208e4b17023SJohn Marino 	     we don't need to insert the same assertion again.  Note
4209e4b17023SJohn Marino 	     that we don't check strict dominance here to avoid
4210e4b17023SJohn Marino 	     replicating the same assertion inside the same basic
4211e4b17023SJohn Marino 	     block more than once (e.g., when a pointer is
4212e4b17023SJohn Marino 	     dereferenced several times inside a block).
4213e4b17023SJohn Marino 
4214e4b17023SJohn Marino 	     An exception to this rule are edge insertions.  If the
4215e4b17023SJohn Marino 	     new assertion is to be inserted on edge E, then it will
4216e4b17023SJohn Marino 	     dominate all the other insertions that we may want to
4217e4b17023SJohn Marino 	     insert in DEST_BB.  So, if we are doing an edge
4218e4b17023SJohn Marino 	     insertion, don't do this dominance check.  */
4219e4b17023SJohn Marino           if (e == NULL
4220e4b17023SJohn Marino 	      && dominated_by_p (CDI_DOMINATORS, dest_bb, loc->bb))
4221e4b17023SJohn Marino 	    return;
4222e4b17023SJohn Marino 
4223e4b17023SJohn Marino 	  /* Otherwise, if E is not a critical edge and DEST_BB
4224e4b17023SJohn Marino 	     dominates the existing location for the assertion, move
4225e4b17023SJohn Marino 	     the assertion up in the dominance tree by updating its
4226e4b17023SJohn Marino 	     location information.  */
4227e4b17023SJohn Marino 	  if ((e == NULL || !EDGE_CRITICAL_P (e))
4228e4b17023SJohn Marino 	      && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
4229e4b17023SJohn Marino 	    {
4230e4b17023SJohn Marino 	      loc->bb = dest_bb;
4231e4b17023SJohn Marino 	      loc->e = e;
4232e4b17023SJohn Marino 	      loc->si = si;
4233e4b17023SJohn Marino 	      return;
4234e4b17023SJohn Marino 	    }
4235e4b17023SJohn Marino 	}
4236e4b17023SJohn Marino 
4237e4b17023SJohn Marino       /* Update the last node of the list and move to the next one.  */
4238e4b17023SJohn Marino       last_loc = loc;
4239e4b17023SJohn Marino       loc = loc->next;
4240e4b17023SJohn Marino     }
4241e4b17023SJohn Marino 
4242e4b17023SJohn Marino   /* If we didn't find an assertion already registered for
4243e4b17023SJohn Marino      NAME COMP_CODE VAL, add a new one at the end of the list of
4244e4b17023SJohn Marino      assertions associated with NAME.  */
4245e4b17023SJohn Marino   n = XNEW (struct assert_locus_d);
4246e4b17023SJohn Marino   n->bb = dest_bb;
4247e4b17023SJohn Marino   n->e = e;
4248e4b17023SJohn Marino   n->si = si;
4249e4b17023SJohn Marino   n->comp_code = comp_code;
4250e4b17023SJohn Marino   n->val = val;
4251e4b17023SJohn Marino   n->expr = expr;
4252e4b17023SJohn Marino   n->next = NULL;
4253e4b17023SJohn Marino 
4254e4b17023SJohn Marino   if (last_loc)
4255e4b17023SJohn Marino     last_loc->next = n;
4256e4b17023SJohn Marino   else
4257e4b17023SJohn Marino     asserts_for[SSA_NAME_VERSION (name)] = n;
4258e4b17023SJohn Marino 
4259e4b17023SJohn Marino   bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
4260e4b17023SJohn Marino }
4261e4b17023SJohn Marino 
4262e4b17023SJohn Marino /* (COND_OP0 COND_CODE COND_OP1) is a predicate which uses NAME.
4263e4b17023SJohn Marino    Extract a suitable test code and value and store them into *CODE_P and
4264e4b17023SJohn Marino    *VAL_P so the predicate is normalized to NAME *CODE_P *VAL_P.
4265e4b17023SJohn Marino 
4266e4b17023SJohn Marino    If no extraction was possible, return FALSE, otherwise return TRUE.
4267e4b17023SJohn Marino 
4268e4b17023SJohn Marino    If INVERT is true, then we invert the result stored into *CODE_P.  */
4269e4b17023SJohn Marino 
4270e4b17023SJohn Marino static bool
extract_code_and_val_from_cond_with_ops(tree name,enum tree_code cond_code,tree cond_op0,tree cond_op1,bool invert,enum tree_code * code_p,tree * val_p)4271e4b17023SJohn Marino extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
4272e4b17023SJohn Marino 					 tree cond_op0, tree cond_op1,
4273e4b17023SJohn Marino 					 bool invert, enum tree_code *code_p,
4274e4b17023SJohn Marino 					 tree *val_p)
4275e4b17023SJohn Marino {
4276e4b17023SJohn Marino   enum tree_code comp_code;
4277e4b17023SJohn Marino   tree val;
4278e4b17023SJohn Marino 
4279e4b17023SJohn Marino   /* Otherwise, we have a comparison of the form NAME COMP VAL
4280e4b17023SJohn Marino      or VAL COMP NAME.  */
4281e4b17023SJohn Marino   if (name == cond_op1)
4282e4b17023SJohn Marino     {
4283e4b17023SJohn Marino       /* If the predicate is of the form VAL COMP NAME, flip
4284e4b17023SJohn Marino 	 COMP around because we need to register NAME as the
4285e4b17023SJohn Marino 	 first operand in the predicate.  */
4286e4b17023SJohn Marino       comp_code = swap_tree_comparison (cond_code);
4287e4b17023SJohn Marino       val = cond_op0;
4288e4b17023SJohn Marino     }
4289e4b17023SJohn Marino   else
4290e4b17023SJohn Marino     {
4291e4b17023SJohn Marino       /* The comparison is of the form NAME COMP VAL, so the
4292e4b17023SJohn Marino 	 comparison code remains unchanged.  */
4293e4b17023SJohn Marino       comp_code = cond_code;
4294e4b17023SJohn Marino       val = cond_op1;
4295e4b17023SJohn Marino     }
4296e4b17023SJohn Marino 
4297e4b17023SJohn Marino   /* Invert the comparison code as necessary.  */
4298e4b17023SJohn Marino   if (invert)
4299e4b17023SJohn Marino     comp_code = invert_tree_comparison (comp_code, 0);
4300e4b17023SJohn Marino 
4301e4b17023SJohn Marino   /* VRP does not handle float types.  */
4302e4b17023SJohn Marino   if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (val)))
4303e4b17023SJohn Marino     return false;
4304e4b17023SJohn Marino 
4305e4b17023SJohn Marino   /* Do not register always-false predicates.
4306e4b17023SJohn Marino      FIXME:  this works around a limitation in fold() when dealing with
4307e4b17023SJohn Marino      enumerations.  Given 'enum { N1, N2 } x;', fold will not
4308e4b17023SJohn Marino      fold 'if (x > N2)' to 'if (0)'.  */
4309e4b17023SJohn Marino   if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
4310e4b17023SJohn Marino       && INTEGRAL_TYPE_P (TREE_TYPE (val)))
4311e4b17023SJohn Marino     {
4312e4b17023SJohn Marino       tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
4313e4b17023SJohn Marino       tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
4314e4b17023SJohn Marino 
4315e4b17023SJohn Marino       if (comp_code == GT_EXPR
4316e4b17023SJohn Marino 	  && (!max
4317e4b17023SJohn Marino 	      || compare_values (val, max) == 0))
4318e4b17023SJohn Marino 	return false;
4319e4b17023SJohn Marino 
4320e4b17023SJohn Marino       if (comp_code == LT_EXPR
4321e4b17023SJohn Marino 	  && (!min
4322e4b17023SJohn Marino 	      || compare_values (val, min) == 0))
4323e4b17023SJohn Marino 	return false;
4324e4b17023SJohn Marino     }
4325e4b17023SJohn Marino   *code_p = comp_code;
4326e4b17023SJohn Marino   *val_p = val;
4327e4b17023SJohn Marino   return true;
4328e4b17023SJohn Marino }
4329e4b17023SJohn Marino 
4330e4b17023SJohn Marino /* Try to register an edge assertion for SSA name NAME on edge E for
4331e4b17023SJohn Marino    the condition COND contributing to the conditional jump pointed to by BSI.
4332e4b17023SJohn Marino    Invert the condition COND if INVERT is true.
4333e4b17023SJohn Marino    Return true if an assertion for NAME could be registered.  */
4334e4b17023SJohn Marino 
4335e4b17023SJohn Marino static bool
register_edge_assert_for_2(tree name,edge e,gimple_stmt_iterator bsi,enum tree_code cond_code,tree cond_op0,tree cond_op1,bool invert)4336e4b17023SJohn Marino register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
4337e4b17023SJohn Marino 			    enum tree_code cond_code,
4338e4b17023SJohn Marino 			    tree cond_op0, tree cond_op1, bool invert)
4339e4b17023SJohn Marino {
4340e4b17023SJohn Marino   tree val;
4341e4b17023SJohn Marino   enum tree_code comp_code;
4342e4b17023SJohn Marino   bool retval = false;
4343e4b17023SJohn Marino 
4344e4b17023SJohn Marino   if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
4345e4b17023SJohn Marino 						cond_op0,
4346e4b17023SJohn Marino 						cond_op1,
4347e4b17023SJohn Marino 						invert, &comp_code, &val))
4348e4b17023SJohn Marino     return false;
4349e4b17023SJohn Marino 
4350e4b17023SJohn Marino   /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
4351e4b17023SJohn Marino      reachable from E.  */
4352e4b17023SJohn Marino   if (live_on_edge (e, name)
4353e4b17023SJohn Marino       && !has_single_use (name))
4354e4b17023SJohn Marino     {
4355e4b17023SJohn Marino       register_new_assert_for (name, name, comp_code, val, NULL, e, bsi);
4356e4b17023SJohn Marino       retval = true;
4357e4b17023SJohn Marino     }
4358e4b17023SJohn Marino 
4359e4b17023SJohn Marino   /* In the case of NAME <= CST and NAME being defined as
4360e4b17023SJohn Marino      NAME = (unsigned) NAME2 + CST2 we can assert NAME2 >= -CST2
4361e4b17023SJohn Marino      and NAME2 <= CST - CST2.  We can do the same for NAME > CST.
4362e4b17023SJohn Marino      This catches range and anti-range tests.  */
4363e4b17023SJohn Marino   if ((comp_code == LE_EXPR
4364e4b17023SJohn Marino        || comp_code == GT_EXPR)
4365e4b17023SJohn Marino       && TREE_CODE (val) == INTEGER_CST
4366e4b17023SJohn Marino       && TYPE_UNSIGNED (TREE_TYPE (val)))
4367e4b17023SJohn Marino     {
4368e4b17023SJohn Marino       gimple def_stmt = SSA_NAME_DEF_STMT (name);
4369e4b17023SJohn Marino       tree cst2 = NULL_TREE, name2 = NULL_TREE, name3 = NULL_TREE;
4370e4b17023SJohn Marino 
4371e4b17023SJohn Marino       /* Extract CST2 from the (optional) addition.  */
4372e4b17023SJohn Marino       if (is_gimple_assign (def_stmt)
4373e4b17023SJohn Marino 	  && gimple_assign_rhs_code (def_stmt) == PLUS_EXPR)
4374e4b17023SJohn Marino 	{
4375e4b17023SJohn Marino 	  name2 = gimple_assign_rhs1 (def_stmt);
4376e4b17023SJohn Marino 	  cst2 = gimple_assign_rhs2 (def_stmt);
4377e4b17023SJohn Marino 	  if (TREE_CODE (name2) == SSA_NAME
4378e4b17023SJohn Marino 	      && TREE_CODE (cst2) == INTEGER_CST)
4379e4b17023SJohn Marino 	    def_stmt = SSA_NAME_DEF_STMT (name2);
4380e4b17023SJohn Marino 	}
4381e4b17023SJohn Marino 
4382e4b17023SJohn Marino       /* Extract NAME2 from the (optional) sign-changing cast.  */
4383e4b17023SJohn Marino       if (gimple_assign_cast_p (def_stmt))
4384e4b17023SJohn Marino 	{
4385e4b17023SJohn Marino 	  if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
4386e4b17023SJohn Marino 	      && ! TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
4387e4b17023SJohn Marino 	      && (TYPE_PRECISION (gimple_expr_type (def_stmt))
4388e4b17023SJohn Marino 		  == TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))))
4389e4b17023SJohn Marino 	    name3 = gimple_assign_rhs1 (def_stmt);
4390e4b17023SJohn Marino 	}
4391e4b17023SJohn Marino 
4392e4b17023SJohn Marino       /* If name3 is used later, create an ASSERT_EXPR for it.  */
4393e4b17023SJohn Marino       if (name3 != NULL_TREE
4394e4b17023SJohn Marino       	  && TREE_CODE (name3) == SSA_NAME
4395e4b17023SJohn Marino 	  && (cst2 == NULL_TREE
4396e4b17023SJohn Marino 	      || TREE_CODE (cst2) == INTEGER_CST)
4397e4b17023SJohn Marino 	  && INTEGRAL_TYPE_P (TREE_TYPE (name3))
4398e4b17023SJohn Marino 	  && live_on_edge (e, name3)
4399e4b17023SJohn Marino 	  && !has_single_use (name3))
4400e4b17023SJohn Marino 	{
4401e4b17023SJohn Marino 	  tree tmp;
4402e4b17023SJohn Marino 
4403e4b17023SJohn Marino 	  /* Build an expression for the range test.  */
4404e4b17023SJohn Marino 	  tmp = build1 (NOP_EXPR, TREE_TYPE (name), name3);
4405e4b17023SJohn Marino 	  if (cst2 != NULL_TREE)
4406e4b17023SJohn Marino 	    tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
4407e4b17023SJohn Marino 
4408e4b17023SJohn Marino 	  if (dump_file)
4409e4b17023SJohn Marino 	    {
4410e4b17023SJohn Marino 	      fprintf (dump_file, "Adding assert for ");
4411e4b17023SJohn Marino 	      print_generic_expr (dump_file, name3, 0);
4412e4b17023SJohn Marino 	      fprintf (dump_file, " from ");
4413e4b17023SJohn Marino 	      print_generic_expr (dump_file, tmp, 0);
4414e4b17023SJohn Marino 	      fprintf (dump_file, "\n");
4415e4b17023SJohn Marino 	    }
4416e4b17023SJohn Marino 
4417e4b17023SJohn Marino 	  register_new_assert_for (name3, tmp, comp_code, val, NULL, e, bsi);
4418e4b17023SJohn Marino 
4419e4b17023SJohn Marino 	  retval = true;
4420e4b17023SJohn Marino 	}
4421e4b17023SJohn Marino 
4422e4b17023SJohn Marino       /* If name2 is used later, create an ASSERT_EXPR for it.  */
4423e4b17023SJohn Marino       if (name2 != NULL_TREE
4424e4b17023SJohn Marino       	  && TREE_CODE (name2) == SSA_NAME
4425e4b17023SJohn Marino 	  && TREE_CODE (cst2) == INTEGER_CST
4426e4b17023SJohn Marino 	  && INTEGRAL_TYPE_P (TREE_TYPE (name2))
4427e4b17023SJohn Marino 	  && live_on_edge (e, name2)
4428e4b17023SJohn Marino 	  && !has_single_use (name2))
4429e4b17023SJohn Marino 	{
4430e4b17023SJohn Marino 	  tree tmp;
4431e4b17023SJohn Marino 
4432e4b17023SJohn Marino 	  /* Build an expression for the range test.  */
4433e4b17023SJohn Marino 	  tmp = name2;
4434e4b17023SJohn Marino 	  if (TREE_TYPE (name) != TREE_TYPE (name2))
4435e4b17023SJohn Marino 	    tmp = build1 (NOP_EXPR, TREE_TYPE (name), tmp);
4436e4b17023SJohn Marino 	  if (cst2 != NULL_TREE)
4437e4b17023SJohn Marino 	    tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
4438e4b17023SJohn Marino 
4439e4b17023SJohn Marino 	  if (dump_file)
4440e4b17023SJohn Marino 	    {
4441e4b17023SJohn Marino 	      fprintf (dump_file, "Adding assert for ");
4442e4b17023SJohn Marino 	      print_generic_expr (dump_file, name2, 0);
4443e4b17023SJohn Marino 	      fprintf (dump_file, " from ");
4444e4b17023SJohn Marino 	      print_generic_expr (dump_file, tmp, 0);
4445e4b17023SJohn Marino 	      fprintf (dump_file, "\n");
4446e4b17023SJohn Marino 	    }
4447e4b17023SJohn Marino 
4448e4b17023SJohn Marino 	  register_new_assert_for (name2, tmp, comp_code, val, NULL, e, bsi);
4449e4b17023SJohn Marino 
4450e4b17023SJohn Marino 	  retval = true;
4451e4b17023SJohn Marino 	}
4452e4b17023SJohn Marino     }
4453e4b17023SJohn Marino 
4454e4b17023SJohn Marino   return retval;
4455e4b17023SJohn Marino }
4456e4b17023SJohn Marino 
4457e4b17023SJohn Marino /* OP is an operand of a truth value expression which is known to have
4458e4b17023SJohn Marino    a particular value.  Register any asserts for OP and for any
4459e4b17023SJohn Marino    operands in OP's defining statement.
4460e4b17023SJohn Marino 
4461e4b17023SJohn Marino    If CODE is EQ_EXPR, then we want to register OP is zero (false),
4462e4b17023SJohn Marino    if CODE is NE_EXPR, then we want to register OP is nonzero (true).   */
4463e4b17023SJohn Marino 
4464e4b17023SJohn Marino static bool
register_edge_assert_for_1(tree op,enum tree_code code,edge e,gimple_stmt_iterator bsi)4465e4b17023SJohn Marino register_edge_assert_for_1 (tree op, enum tree_code code,
4466e4b17023SJohn Marino 			    edge e, gimple_stmt_iterator bsi)
4467e4b17023SJohn Marino {
4468e4b17023SJohn Marino   bool retval = false;
4469e4b17023SJohn Marino   gimple op_def;
4470e4b17023SJohn Marino   tree val;
4471e4b17023SJohn Marino   enum tree_code rhs_code;
4472e4b17023SJohn Marino 
4473e4b17023SJohn Marino   /* We only care about SSA_NAMEs.  */
4474e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
4475e4b17023SJohn Marino     return false;
4476e4b17023SJohn Marino 
4477e4b17023SJohn Marino   /* We know that OP will have a zero or nonzero value.  If OP is used
4478e4b17023SJohn Marino      more than once go ahead and register an assert for OP.
4479e4b17023SJohn Marino 
4480e4b17023SJohn Marino      The FOUND_IN_SUBGRAPH support is not helpful in this situation as
4481e4b17023SJohn Marino      it will always be set for OP (because OP is used in a COND_EXPR in
4482e4b17023SJohn Marino      the subgraph).  */
4483e4b17023SJohn Marino   if (!has_single_use (op))
4484e4b17023SJohn Marino     {
4485e4b17023SJohn Marino       val = build_int_cst (TREE_TYPE (op), 0);
4486e4b17023SJohn Marino       register_new_assert_for (op, op, code, val, NULL, e, bsi);
4487e4b17023SJohn Marino       retval = true;
4488e4b17023SJohn Marino     }
4489e4b17023SJohn Marino 
4490e4b17023SJohn Marino   /* Now look at how OP is set.  If it's set from a comparison,
4491e4b17023SJohn Marino      a truth operation or some bit operations, then we may be able
4492e4b17023SJohn Marino      to register information about the operands of that assignment.  */
4493e4b17023SJohn Marino   op_def = SSA_NAME_DEF_STMT (op);
4494e4b17023SJohn Marino   if (gimple_code (op_def) != GIMPLE_ASSIGN)
4495e4b17023SJohn Marino     return retval;
4496e4b17023SJohn Marino 
4497e4b17023SJohn Marino   rhs_code = gimple_assign_rhs_code (op_def);
4498e4b17023SJohn Marino 
4499e4b17023SJohn Marino   if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
4500e4b17023SJohn Marino     {
4501e4b17023SJohn Marino       bool invert = (code == EQ_EXPR ? true : false);
4502e4b17023SJohn Marino       tree op0 = gimple_assign_rhs1 (op_def);
4503e4b17023SJohn Marino       tree op1 = gimple_assign_rhs2 (op_def);
4504e4b17023SJohn Marino 
4505e4b17023SJohn Marino       if (TREE_CODE (op0) == SSA_NAME)
4506e4b17023SJohn Marino         retval |= register_edge_assert_for_2 (op0, e, bsi, rhs_code, op0, op1,
4507e4b17023SJohn Marino 					      invert);
4508e4b17023SJohn Marino       if (TREE_CODE (op1) == SSA_NAME)
4509e4b17023SJohn Marino         retval |= register_edge_assert_for_2 (op1, e, bsi, rhs_code, op0, op1,
4510e4b17023SJohn Marino 					      invert);
4511e4b17023SJohn Marino     }
4512e4b17023SJohn Marino   else if ((code == NE_EXPR
4513e4b17023SJohn Marino 	    && gimple_assign_rhs_code (op_def) == BIT_AND_EXPR)
4514e4b17023SJohn Marino 	   || (code == EQ_EXPR
4515e4b17023SJohn Marino 	       && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
4516e4b17023SJohn Marino     {
4517e4b17023SJohn Marino       /* Recurse on each operand.  */
4518e4b17023SJohn Marino       retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4519e4b17023SJohn Marino 					    code, e, bsi);
4520e4b17023SJohn Marino       retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
4521e4b17023SJohn Marino 					    code, e, bsi);
4522e4b17023SJohn Marino     }
4523e4b17023SJohn Marino   else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
4524e4b17023SJohn Marino 	   && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
4525e4b17023SJohn Marino     {
4526e4b17023SJohn Marino       /* Recurse, flipping CODE.  */
4527e4b17023SJohn Marino       code = invert_tree_comparison (code, false);
4528e4b17023SJohn Marino       retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4529e4b17023SJohn Marino 					    code, e, bsi);
4530e4b17023SJohn Marino     }
4531e4b17023SJohn Marino   else if (gimple_assign_rhs_code (op_def) == SSA_NAME)
4532e4b17023SJohn Marino     {
4533e4b17023SJohn Marino       /* Recurse through the copy.  */
4534e4b17023SJohn Marino       retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4535e4b17023SJohn Marino 					    code, e, bsi);
4536e4b17023SJohn Marino     }
4537e4b17023SJohn Marino   else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def)))
4538e4b17023SJohn Marino     {
4539*95d28233SJohn Marino       /* Recurse through the type conversion, unless it is a narrowing
4540*95d28233SJohn Marino 	 conversion or conversion from non-integral type.  */
4541*95d28233SJohn Marino       tree rhs = gimple_assign_rhs1 (op_def);
4542*95d28233SJohn Marino       if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
4543*95d28233SJohn Marino 	  && (TYPE_PRECISION (TREE_TYPE (rhs))
4544*95d28233SJohn Marino 	      <= TYPE_PRECISION (TREE_TYPE (op))))
4545*95d28233SJohn Marino 	retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
4546e4b17023SJohn Marino     }
4547e4b17023SJohn Marino 
4548e4b17023SJohn Marino   return retval;
4549e4b17023SJohn Marino }
4550e4b17023SJohn Marino 
4551e4b17023SJohn Marino /* Try to register an edge assertion for SSA name NAME on edge E for
4552e4b17023SJohn Marino    the condition COND contributing to the conditional jump pointed to by SI.
4553e4b17023SJohn Marino    Return true if an assertion for NAME could be registered.  */
4554e4b17023SJohn Marino 
4555e4b17023SJohn Marino static bool
register_edge_assert_for(tree name,edge e,gimple_stmt_iterator si,enum tree_code cond_code,tree cond_op0,tree cond_op1)4556e4b17023SJohn Marino register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
4557e4b17023SJohn Marino 			  enum tree_code cond_code, tree cond_op0,
4558e4b17023SJohn Marino 			  tree cond_op1)
4559e4b17023SJohn Marino {
4560e4b17023SJohn Marino   tree val;
4561e4b17023SJohn Marino   enum tree_code comp_code;
4562e4b17023SJohn Marino   bool retval = false;
4563e4b17023SJohn Marino   bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;
4564e4b17023SJohn Marino 
4565e4b17023SJohn Marino   /* Do not attempt to infer anything in names that flow through
4566e4b17023SJohn Marino      abnormal edges.  */
4567e4b17023SJohn Marino   if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
4568e4b17023SJohn Marino     return false;
4569e4b17023SJohn Marino 
4570e4b17023SJohn Marino   if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
4571e4b17023SJohn Marino 						cond_op0, cond_op1,
4572e4b17023SJohn Marino 						is_else_edge,
4573e4b17023SJohn Marino 						&comp_code, &val))
4574e4b17023SJohn Marino     return false;
4575e4b17023SJohn Marino 
4576e4b17023SJohn Marino   /* Register ASSERT_EXPRs for name.  */
4577e4b17023SJohn Marino   retval |= register_edge_assert_for_2 (name, e, si, cond_code, cond_op0,
4578e4b17023SJohn Marino 					cond_op1, is_else_edge);
4579e4b17023SJohn Marino 
4580e4b17023SJohn Marino 
4581e4b17023SJohn Marino   /* If COND is effectively an equality test of an SSA_NAME against
4582e4b17023SJohn Marino      the value zero or one, then we may be able to assert values
4583e4b17023SJohn Marino      for SSA_NAMEs which flow into COND.  */
4584e4b17023SJohn Marino 
4585e4b17023SJohn Marino   /* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
4586e4b17023SJohn Marino      statement of NAME we can assert both operands of the BIT_AND_EXPR
4587e4b17023SJohn Marino      have nonzero value.  */
4588e4b17023SJohn Marino   if (((comp_code == EQ_EXPR && integer_onep (val))
4589e4b17023SJohn Marino        || (comp_code == NE_EXPR && integer_zerop (val))))
4590e4b17023SJohn Marino     {
4591e4b17023SJohn Marino       gimple def_stmt = SSA_NAME_DEF_STMT (name);
4592e4b17023SJohn Marino 
4593e4b17023SJohn Marino       if (is_gimple_assign (def_stmt)
4594e4b17023SJohn Marino 	  && gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR)
4595e4b17023SJohn Marino 	{
4596e4b17023SJohn Marino 	  tree op0 = gimple_assign_rhs1 (def_stmt);
4597e4b17023SJohn Marino 	  tree op1 = gimple_assign_rhs2 (def_stmt);
4598e4b17023SJohn Marino 	  retval |= register_edge_assert_for_1 (op0, NE_EXPR, e, si);
4599e4b17023SJohn Marino 	  retval |= register_edge_assert_for_1 (op1, NE_EXPR, e, si);
4600e4b17023SJohn Marino 	}
4601e4b17023SJohn Marino     }
4602e4b17023SJohn Marino 
4603e4b17023SJohn Marino   /* In the case of NAME == 0 or NAME != 1, for BIT_IOR_EXPR defining
4604e4b17023SJohn Marino      statement of NAME we can assert both operands of the BIT_IOR_EXPR
4605e4b17023SJohn Marino      have zero value.  */
4606e4b17023SJohn Marino   if (((comp_code == EQ_EXPR && integer_zerop (val))
4607e4b17023SJohn Marino        || (comp_code == NE_EXPR && integer_onep (val))))
4608e4b17023SJohn Marino     {
4609e4b17023SJohn Marino       gimple def_stmt = SSA_NAME_DEF_STMT (name);
4610e4b17023SJohn Marino 
4611e4b17023SJohn Marino       /* For BIT_IOR_EXPR only if NAME == 0 both operands have
4612e4b17023SJohn Marino 	 necessarily zero value, or if type-precision is one.  */
4613e4b17023SJohn Marino       if (is_gimple_assign (def_stmt)
4614e4b17023SJohn Marino 	  && (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR
4615e4b17023SJohn Marino 	      && (TYPE_PRECISION (TREE_TYPE (name)) == 1
4616e4b17023SJohn Marino 	          || comp_code == EQ_EXPR)))
4617e4b17023SJohn Marino 	{
4618e4b17023SJohn Marino 	  tree op0 = gimple_assign_rhs1 (def_stmt);
4619e4b17023SJohn Marino 	  tree op1 = gimple_assign_rhs2 (def_stmt);
4620e4b17023SJohn Marino 	  retval |= register_edge_assert_for_1 (op0, EQ_EXPR, e, si);
4621e4b17023SJohn Marino 	  retval |= register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
4622e4b17023SJohn Marino 	}
4623e4b17023SJohn Marino     }
4624e4b17023SJohn Marino 
4625e4b17023SJohn Marino   return retval;
4626e4b17023SJohn Marino }
4627e4b17023SJohn Marino 
4628e4b17023SJohn Marino 
4629e4b17023SJohn Marino /* Determine whether the outgoing edges of BB should receive an
4630e4b17023SJohn Marino    ASSERT_EXPR for each of the operands of BB's LAST statement.
4631e4b17023SJohn Marino    The last statement of BB must be a COND_EXPR.
4632e4b17023SJohn Marino 
4633e4b17023SJohn Marino    If any of the sub-graphs rooted at BB have an interesting use of
4634e4b17023SJohn Marino    the predicate operands, an assert location node is added to the
4635e4b17023SJohn Marino    list of assertions for the corresponding operands.  */
4636e4b17023SJohn Marino 
4637e4b17023SJohn Marino static bool
find_conditional_asserts(basic_block bb,gimple last)4638e4b17023SJohn Marino find_conditional_asserts (basic_block bb, gimple last)
4639e4b17023SJohn Marino {
4640e4b17023SJohn Marino   bool need_assert;
4641e4b17023SJohn Marino   gimple_stmt_iterator bsi;
4642e4b17023SJohn Marino   tree op;
4643e4b17023SJohn Marino   edge_iterator ei;
4644e4b17023SJohn Marino   edge e;
4645e4b17023SJohn Marino   ssa_op_iter iter;
4646e4b17023SJohn Marino 
4647e4b17023SJohn Marino   need_assert = false;
4648e4b17023SJohn Marino   bsi = gsi_for_stmt (last);
4649e4b17023SJohn Marino 
4650e4b17023SJohn Marino   /* Look for uses of the operands in each of the sub-graphs
4651e4b17023SJohn Marino      rooted at BB.  We need to check each of the outgoing edges
4652e4b17023SJohn Marino      separately, so that we know what kind of ASSERT_EXPR to
4653e4b17023SJohn Marino      insert.  */
4654e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, bb->succs)
4655e4b17023SJohn Marino     {
4656e4b17023SJohn Marino       if (e->dest == bb)
4657e4b17023SJohn Marino 	continue;
4658e4b17023SJohn Marino 
4659e4b17023SJohn Marino       /* Register the necessary assertions for each operand in the
4660e4b17023SJohn Marino 	 conditional predicate.  */
4661e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
4662e4b17023SJohn Marino 	{
4663e4b17023SJohn Marino 	  need_assert |= register_edge_assert_for (op, e, bsi,
4664e4b17023SJohn Marino 						   gimple_cond_code (last),
4665e4b17023SJohn Marino 						   gimple_cond_lhs (last),
4666e4b17023SJohn Marino 						   gimple_cond_rhs (last));
4667e4b17023SJohn Marino 	}
4668e4b17023SJohn Marino     }
4669e4b17023SJohn Marino 
4670e4b17023SJohn Marino   return need_assert;
4671e4b17023SJohn Marino }
4672e4b17023SJohn Marino 
4673e4b17023SJohn Marino struct case_info
4674e4b17023SJohn Marino {
4675e4b17023SJohn Marino   tree expr;
4676e4b17023SJohn Marino   basic_block bb;
4677e4b17023SJohn Marino };
4678e4b17023SJohn Marino 
4679e4b17023SJohn Marino /* Compare two case labels sorting first by the destination bb index
4680e4b17023SJohn Marino    and then by the case value.  */
4681e4b17023SJohn Marino 
4682e4b17023SJohn Marino static int
compare_case_labels(const void * p1,const void * p2)4683e4b17023SJohn Marino compare_case_labels (const void *p1, const void *p2)
4684e4b17023SJohn Marino {
4685e4b17023SJohn Marino   const struct case_info *ci1 = (const struct case_info *) p1;
4686e4b17023SJohn Marino   const struct case_info *ci2 = (const struct case_info *) p2;
4687e4b17023SJohn Marino   int idx1 = ci1->bb->index;
4688e4b17023SJohn Marino   int idx2 = ci2->bb->index;
4689e4b17023SJohn Marino 
4690e4b17023SJohn Marino   if (idx1 < idx2)
4691e4b17023SJohn Marino     return -1;
4692e4b17023SJohn Marino   else if (idx1 == idx2)
4693e4b17023SJohn Marino     {
4694e4b17023SJohn Marino       /* Make sure the default label is first in a group.  */
4695e4b17023SJohn Marino       if (!CASE_LOW (ci1->expr))
4696e4b17023SJohn Marino 	return -1;
4697e4b17023SJohn Marino       else if (!CASE_LOW (ci2->expr))
4698e4b17023SJohn Marino 	return 1;
4699e4b17023SJohn Marino       else
4700e4b17023SJohn Marino 	return tree_int_cst_compare (CASE_LOW (ci1->expr),
4701e4b17023SJohn Marino 				     CASE_LOW (ci2->expr));
4702e4b17023SJohn Marino     }
4703e4b17023SJohn Marino   else
4704e4b17023SJohn Marino     return 1;
4705e4b17023SJohn Marino }
4706e4b17023SJohn Marino 
4707e4b17023SJohn Marino /* Determine whether the outgoing edges of BB should receive an
4708e4b17023SJohn Marino    ASSERT_EXPR for each of the operands of BB's LAST statement.
4709e4b17023SJohn Marino    The last statement of BB must be a SWITCH_EXPR.
4710e4b17023SJohn Marino 
4711e4b17023SJohn Marino    If any of the sub-graphs rooted at BB have an interesting use of
4712e4b17023SJohn Marino    the predicate operands, an assert location node is added to the
4713e4b17023SJohn Marino    list of assertions for the corresponding operands.  */
4714e4b17023SJohn Marino 
4715e4b17023SJohn Marino static bool
find_switch_asserts(basic_block bb,gimple last)4716e4b17023SJohn Marino find_switch_asserts (basic_block bb, gimple last)
4717e4b17023SJohn Marino {
4718e4b17023SJohn Marino   bool need_assert;
4719e4b17023SJohn Marino   gimple_stmt_iterator bsi;
4720e4b17023SJohn Marino   tree op;
4721e4b17023SJohn Marino   edge e;
4722e4b17023SJohn Marino   struct case_info *ci;
4723e4b17023SJohn Marino   size_t n = gimple_switch_num_labels (last);
4724e4b17023SJohn Marino #if GCC_VERSION >= 4000
4725e4b17023SJohn Marino   unsigned int idx;
4726e4b17023SJohn Marino #else
4727e4b17023SJohn Marino   /* Work around GCC 3.4 bug (PR 37086).  */
4728e4b17023SJohn Marino   volatile unsigned int idx;
4729e4b17023SJohn Marino #endif
4730e4b17023SJohn Marino 
4731e4b17023SJohn Marino   need_assert = false;
4732e4b17023SJohn Marino   bsi = gsi_for_stmt (last);
4733e4b17023SJohn Marino   op = gimple_switch_index (last);
4734e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
4735e4b17023SJohn Marino     return false;
4736e4b17023SJohn Marino 
4737e4b17023SJohn Marino   /* Build a vector of case labels sorted by destination label.  */
4738e4b17023SJohn Marino   ci = XNEWVEC (struct case_info, n);
4739e4b17023SJohn Marino   for (idx = 0; idx < n; ++idx)
4740e4b17023SJohn Marino     {
4741e4b17023SJohn Marino       ci[idx].expr = gimple_switch_label (last, idx);
4742e4b17023SJohn Marino       ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
4743e4b17023SJohn Marino     }
4744e4b17023SJohn Marino   qsort (ci, n, sizeof (struct case_info), compare_case_labels);
4745e4b17023SJohn Marino 
4746e4b17023SJohn Marino   for (idx = 0; idx < n; ++idx)
4747e4b17023SJohn Marino     {
4748e4b17023SJohn Marino       tree min, max;
4749e4b17023SJohn Marino       tree cl = ci[idx].expr;
4750e4b17023SJohn Marino       basic_block cbb = ci[idx].bb;
4751e4b17023SJohn Marino 
4752e4b17023SJohn Marino       min = CASE_LOW (cl);
4753e4b17023SJohn Marino       max = CASE_HIGH (cl);
4754e4b17023SJohn Marino 
4755e4b17023SJohn Marino       /* If there are multiple case labels with the same destination
4756e4b17023SJohn Marino 	 we need to combine them to a single value range for the edge.  */
4757e4b17023SJohn Marino       if (idx + 1 < n && cbb == ci[idx + 1].bb)
4758e4b17023SJohn Marino 	{
4759e4b17023SJohn Marino 	  /* Skip labels until the last of the group.  */
4760e4b17023SJohn Marino 	  do {
4761e4b17023SJohn Marino 	    ++idx;
4762e4b17023SJohn Marino 	  } while (idx < n && cbb == ci[idx].bb);
4763e4b17023SJohn Marino 	  --idx;
4764e4b17023SJohn Marino 
4765e4b17023SJohn Marino 	  /* Pick up the maximum of the case label range.  */
4766e4b17023SJohn Marino 	  if (CASE_HIGH (ci[idx].expr))
4767e4b17023SJohn Marino 	    max = CASE_HIGH (ci[idx].expr);
4768e4b17023SJohn Marino 	  else
4769e4b17023SJohn Marino 	    max = CASE_LOW (ci[idx].expr);
4770e4b17023SJohn Marino 	}
4771e4b17023SJohn Marino 
4772e4b17023SJohn Marino       /* Nothing to do if the range includes the default label until we
4773e4b17023SJohn Marino 	 can register anti-ranges.  */
4774e4b17023SJohn Marino       if (min == NULL_TREE)
4775e4b17023SJohn Marino 	continue;
4776e4b17023SJohn Marino 
4777e4b17023SJohn Marino       /* Find the edge to register the assert expr on.  */
4778e4b17023SJohn Marino       e = find_edge (bb, cbb);
4779e4b17023SJohn Marino 
4780e4b17023SJohn Marino       /* Register the necessary assertions for the operand in the
4781e4b17023SJohn Marino 	 SWITCH_EXPR.  */
4782e4b17023SJohn Marino       need_assert |= register_edge_assert_for (op, e, bsi,
4783e4b17023SJohn Marino 					       max ? GE_EXPR : EQ_EXPR,
4784e4b17023SJohn Marino 					       op,
4785e4b17023SJohn Marino 					       fold_convert (TREE_TYPE (op),
4786e4b17023SJohn Marino 							     min));
4787e4b17023SJohn Marino       if (max)
4788e4b17023SJohn Marino 	{
4789e4b17023SJohn Marino 	  need_assert |= register_edge_assert_for (op, e, bsi, LE_EXPR,
4790e4b17023SJohn Marino 						   op,
4791e4b17023SJohn Marino 						   fold_convert (TREE_TYPE (op),
4792e4b17023SJohn Marino 								 max));
4793e4b17023SJohn Marino 	}
4794e4b17023SJohn Marino     }
4795e4b17023SJohn Marino 
4796e4b17023SJohn Marino   XDELETEVEC (ci);
4797e4b17023SJohn Marino   return need_assert;
4798e4b17023SJohn Marino }
4799e4b17023SJohn Marino 
4800e4b17023SJohn Marino 
4801e4b17023SJohn Marino /* Traverse all the statements in block BB looking for statements that
4802e4b17023SJohn Marino    may generate useful assertions for the SSA names in their operand.
4803e4b17023SJohn Marino    If a statement produces a useful assertion A for name N_i, then the
4804e4b17023SJohn Marino    list of assertions already generated for N_i is scanned to
4805e4b17023SJohn Marino    determine if A is actually needed.
4806e4b17023SJohn Marino 
4807e4b17023SJohn Marino    If N_i already had the assertion A at a location dominating the
4808e4b17023SJohn Marino    current location, then nothing needs to be done.  Otherwise, the
4809e4b17023SJohn Marino    new location for A is recorded instead.
4810e4b17023SJohn Marino 
4811e4b17023SJohn Marino    1- For every statement S in BB, all the variables used by S are
4812e4b17023SJohn Marino       added to bitmap FOUND_IN_SUBGRAPH.
4813e4b17023SJohn Marino 
4814e4b17023SJohn Marino    2- If statement S uses an operand N in a way that exposes a known
4815e4b17023SJohn Marino       value range for N, then if N was not already generated by an
4816e4b17023SJohn Marino       ASSERT_EXPR, create a new assert location for N.  For instance,
4817e4b17023SJohn Marino       if N is a pointer and the statement dereferences it, we can
4818e4b17023SJohn Marino       assume that N is not NULL.
4819e4b17023SJohn Marino 
4820e4b17023SJohn Marino    3- COND_EXPRs are a special case of #2.  We can derive range
4821e4b17023SJohn Marino       information from the predicate but need to insert different
4822e4b17023SJohn Marino       ASSERT_EXPRs for each of the sub-graphs rooted at the
4823e4b17023SJohn Marino       conditional block.  If the last statement of BB is a conditional
4824e4b17023SJohn Marino       expression of the form 'X op Y', then
4825e4b17023SJohn Marino 
4826e4b17023SJohn Marino       a) Remove X and Y from the set FOUND_IN_SUBGRAPH.
4827e4b17023SJohn Marino 
4828e4b17023SJohn Marino       b) If the conditional is the only entry point to the sub-graph
4829e4b17023SJohn Marino 	 corresponding to the THEN_CLAUSE, recurse into it.  On
4830e4b17023SJohn Marino 	 return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
4831e4b17023SJohn Marino 	 an ASSERT_EXPR is added for the corresponding variable.
4832e4b17023SJohn Marino 
4833e4b17023SJohn Marino       c) Repeat step (b) on the ELSE_CLAUSE.
4834e4b17023SJohn Marino 
4835e4b17023SJohn Marino       d) Mark X and Y in FOUND_IN_SUBGRAPH.
4836e4b17023SJohn Marino 
4837e4b17023SJohn Marino       For instance,
4838e4b17023SJohn Marino 
4839e4b17023SJohn Marino 	    if (a == 9)
4840e4b17023SJohn Marino 	      b = a;
4841e4b17023SJohn Marino 	    else
4842e4b17023SJohn Marino 	      b = c + 1;
4843e4b17023SJohn Marino 
4844e4b17023SJohn Marino       In this case, an assertion on the THEN clause is useful to
4845e4b17023SJohn Marino       determine that 'a' is always 9 on that edge.  However, an assertion
4846e4b17023SJohn Marino       on the ELSE clause would be unnecessary.
4847e4b17023SJohn Marino 
4848e4b17023SJohn Marino    4- If BB does not end in a conditional expression, then we recurse
4849e4b17023SJohn Marino       into BB's dominator children.
4850e4b17023SJohn Marino 
4851e4b17023SJohn Marino    At the end of the recursive traversal, every SSA name will have a
4852e4b17023SJohn Marino    list of locations where ASSERT_EXPRs should be added.  When a new
4853e4b17023SJohn Marino    location for name N is found, it is registered by calling
4854e4b17023SJohn Marino    register_new_assert_for.  That function keeps track of all the
4855e4b17023SJohn Marino    registered assertions to prevent adding unnecessary assertions.
4856e4b17023SJohn Marino    For instance, if a pointer P_4 is dereferenced more than once in a
4857e4b17023SJohn Marino    dominator tree, only the location dominating all the dereference of
4858e4b17023SJohn Marino    P_4 will receive an ASSERT_EXPR.
4859e4b17023SJohn Marino 
4860e4b17023SJohn Marino    If this function returns true, then it means that there are names
4861e4b17023SJohn Marino    for which we need to generate ASSERT_EXPRs.  Those assertions are
4862e4b17023SJohn Marino    inserted by process_assert_insertions.  */
4863e4b17023SJohn Marino 
4864e4b17023SJohn Marino static bool
find_assert_locations_1(basic_block bb,sbitmap live)4865e4b17023SJohn Marino find_assert_locations_1 (basic_block bb, sbitmap live)
4866e4b17023SJohn Marino {
4867e4b17023SJohn Marino   gimple_stmt_iterator si;
4868e4b17023SJohn Marino   gimple last;
4869e4b17023SJohn Marino   gimple phi;
4870e4b17023SJohn Marino   bool need_assert;
4871e4b17023SJohn Marino 
4872e4b17023SJohn Marino   need_assert = false;
4873e4b17023SJohn Marino   last = last_stmt (bb);
4874e4b17023SJohn Marino 
4875e4b17023SJohn Marino   /* If BB's last statement is a conditional statement involving integer
4876e4b17023SJohn Marino      operands, determine if we need to add ASSERT_EXPRs.  */
4877e4b17023SJohn Marino   if (last
4878e4b17023SJohn Marino       && gimple_code (last) == GIMPLE_COND
4879e4b17023SJohn Marino       && !fp_predicate (last)
4880e4b17023SJohn Marino       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
4881e4b17023SJohn Marino     need_assert |= find_conditional_asserts (bb, last);
4882e4b17023SJohn Marino 
4883e4b17023SJohn Marino   /* If BB's last statement is a switch statement involving integer
4884e4b17023SJohn Marino      operands, determine if we need to add ASSERT_EXPRs.  */
4885e4b17023SJohn Marino   if (last
4886e4b17023SJohn Marino       && gimple_code (last) == GIMPLE_SWITCH
4887e4b17023SJohn Marino       && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
4888e4b17023SJohn Marino     need_assert |= find_switch_asserts (bb, last);
4889e4b17023SJohn Marino 
4890e4b17023SJohn Marino   /* Traverse all the statements in BB marking used names and looking
4891e4b17023SJohn Marino      for statements that may infer assertions for their used operands.  */
4892e4b17023SJohn Marino   for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
4893e4b17023SJohn Marino     {
4894e4b17023SJohn Marino       gimple stmt;
4895e4b17023SJohn Marino       tree op;
4896e4b17023SJohn Marino       ssa_op_iter i;
4897e4b17023SJohn Marino 
4898e4b17023SJohn Marino       stmt = gsi_stmt (si);
4899e4b17023SJohn Marino 
4900e4b17023SJohn Marino       if (is_gimple_debug (stmt))
4901e4b17023SJohn Marino 	continue;
4902e4b17023SJohn Marino 
4903e4b17023SJohn Marino       /* See if we can derive an assertion for any of STMT's operands.  */
4904e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
4905e4b17023SJohn Marino 	{
4906e4b17023SJohn Marino 	  tree value;
4907e4b17023SJohn Marino 	  enum tree_code comp_code;
4908e4b17023SJohn Marino 
4909e4b17023SJohn Marino 	  /* Mark OP in our live bitmap.  */
4910e4b17023SJohn Marino 	  SET_BIT (live, SSA_NAME_VERSION (op));
4911e4b17023SJohn Marino 
4912e4b17023SJohn Marino 	  /* If OP is used in such a way that we can infer a value
4913e4b17023SJohn Marino 	     range for it, and we don't find a previous assertion for
4914e4b17023SJohn Marino 	     it, create a new assertion location node for OP.  */
4915e4b17023SJohn Marino 	  if (infer_value_range (stmt, op, &comp_code, &value))
4916e4b17023SJohn Marino 	    {
4917e4b17023SJohn Marino 	      /* If we are able to infer a nonzero value range for OP,
4918e4b17023SJohn Marino 		 then walk backwards through the use-def chain to see if OP
4919e4b17023SJohn Marino 		 was set via a typecast.
4920e4b17023SJohn Marino 
4921e4b17023SJohn Marino 		 If so, then we can also infer a nonzero value range
4922e4b17023SJohn Marino 		 for the operand of the NOP_EXPR.  */
4923e4b17023SJohn Marino 	      if (comp_code == NE_EXPR && integer_zerop (value))
4924e4b17023SJohn Marino 		{
4925e4b17023SJohn Marino 		  tree t = op;
4926e4b17023SJohn Marino 		  gimple def_stmt = SSA_NAME_DEF_STMT (t);
4927e4b17023SJohn Marino 
4928e4b17023SJohn Marino 		  while (is_gimple_assign (def_stmt)
4929e4b17023SJohn Marino 			 && gimple_assign_rhs_code (def_stmt)  == NOP_EXPR
4930e4b17023SJohn Marino 			 && TREE_CODE
4931e4b17023SJohn Marino 			     (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
4932e4b17023SJohn Marino 			 && POINTER_TYPE_P
4933e4b17023SJohn Marino 			     (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
4934e4b17023SJohn Marino 		    {
4935e4b17023SJohn Marino 		      t = gimple_assign_rhs1 (def_stmt);
4936e4b17023SJohn Marino 		      def_stmt = SSA_NAME_DEF_STMT (t);
4937e4b17023SJohn Marino 
4938e4b17023SJohn Marino 		      /* Note we want to register the assert for the
4939e4b17023SJohn Marino 			 operand of the NOP_EXPR after SI, not after the
4940e4b17023SJohn Marino 			 conversion.  */
4941e4b17023SJohn Marino 		      if (! has_single_use (t))
4942e4b17023SJohn Marino 			{
4943e4b17023SJohn Marino 			  register_new_assert_for (t, t, comp_code, value,
4944e4b17023SJohn Marino 						   bb, NULL, si);
4945e4b17023SJohn Marino 			  need_assert = true;
4946e4b17023SJohn Marino 			}
4947e4b17023SJohn Marino 		    }
4948e4b17023SJohn Marino 		}
4949e4b17023SJohn Marino 
4950e4b17023SJohn Marino 	      /* If OP is used only once, namely in this STMT, don't
4951e4b17023SJohn Marino 		 bother creating an ASSERT_EXPR for it.  Such an
4952e4b17023SJohn Marino 		 ASSERT_EXPR would do nothing but increase compile time.  */
4953e4b17023SJohn Marino 	      if (!has_single_use (op))
4954e4b17023SJohn Marino 		{
4955e4b17023SJohn Marino 		  register_new_assert_for (op, op, comp_code, value,
4956e4b17023SJohn Marino 					   bb, NULL, si);
4957e4b17023SJohn Marino 		  need_assert = true;
4958e4b17023SJohn Marino 		}
4959e4b17023SJohn Marino 	    }
4960e4b17023SJohn Marino 	}
4961e4b17023SJohn Marino     }
4962e4b17023SJohn Marino 
4963e4b17023SJohn Marino   /* Traverse all PHI nodes in BB marking used operands.  */
4964e4b17023SJohn Marino   for (si = gsi_start_phis (bb); !gsi_end_p(si); gsi_next (&si))
4965e4b17023SJohn Marino     {
4966e4b17023SJohn Marino       use_operand_p arg_p;
4967e4b17023SJohn Marino       ssa_op_iter i;
4968e4b17023SJohn Marino       phi = gsi_stmt (si);
4969e4b17023SJohn Marino 
4970e4b17023SJohn Marino       FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
4971e4b17023SJohn Marino 	{
4972e4b17023SJohn Marino 	  tree arg = USE_FROM_PTR (arg_p);
4973e4b17023SJohn Marino 	  if (TREE_CODE (arg) == SSA_NAME)
4974e4b17023SJohn Marino 	    SET_BIT (live, SSA_NAME_VERSION (arg));
4975e4b17023SJohn Marino 	}
4976e4b17023SJohn Marino     }
4977e4b17023SJohn Marino 
4978e4b17023SJohn Marino   return need_assert;
4979e4b17023SJohn Marino }
4980e4b17023SJohn Marino 
4981e4b17023SJohn Marino /* Do an RPO walk over the function computing SSA name liveness
4982e4b17023SJohn Marino    on-the-fly and deciding on assert expressions to insert.
4983e4b17023SJohn Marino    Returns true if there are assert expressions to be inserted.  */
4984e4b17023SJohn Marino 
4985e4b17023SJohn Marino static bool
find_assert_locations(void)4986e4b17023SJohn Marino find_assert_locations (void)
4987e4b17023SJohn Marino {
4988e4b17023SJohn Marino   int *rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4989e4b17023SJohn Marino   int *bb_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4990e4b17023SJohn Marino   int *last_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4991e4b17023SJohn Marino   int rpo_cnt, i;
4992e4b17023SJohn Marino   bool need_asserts;
4993e4b17023SJohn Marino 
4994e4b17023SJohn Marino   live = XCNEWVEC (sbitmap, last_basic_block + NUM_FIXED_BLOCKS);
4995e4b17023SJohn Marino   rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
4996e4b17023SJohn Marino   for (i = 0; i < rpo_cnt; ++i)
4997e4b17023SJohn Marino     bb_rpo[rpo[i]] = i;
4998e4b17023SJohn Marino 
4999e4b17023SJohn Marino   need_asserts = false;
5000e4b17023SJohn Marino   for (i = rpo_cnt-1; i >= 0; --i)
5001e4b17023SJohn Marino     {
5002e4b17023SJohn Marino       basic_block bb = BASIC_BLOCK (rpo[i]);
5003e4b17023SJohn Marino       edge e;
5004e4b17023SJohn Marino       edge_iterator ei;
5005e4b17023SJohn Marino 
5006e4b17023SJohn Marino       if (!live[rpo[i]])
5007e4b17023SJohn Marino 	{
5008e4b17023SJohn Marino 	  live[rpo[i]] = sbitmap_alloc (num_ssa_names);
5009e4b17023SJohn Marino 	  sbitmap_zero (live[rpo[i]]);
5010e4b17023SJohn Marino 	}
5011e4b17023SJohn Marino 
5012e4b17023SJohn Marino       /* Process BB and update the live information with uses in
5013e4b17023SJohn Marino          this block.  */
5014e4b17023SJohn Marino       need_asserts |= find_assert_locations_1 (bb, live[rpo[i]]);
5015e4b17023SJohn Marino 
5016e4b17023SJohn Marino       /* Merge liveness into the predecessor blocks and free it.  */
5017e4b17023SJohn Marino       if (!sbitmap_empty_p (live[rpo[i]]))
5018e4b17023SJohn Marino 	{
5019e4b17023SJohn Marino 	  int pred_rpo = i;
5020e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, bb->preds)
5021e4b17023SJohn Marino 	    {
5022e4b17023SJohn Marino 	      int pred = e->src->index;
5023e4b17023SJohn Marino 	      if (e->flags & EDGE_DFS_BACK)
5024e4b17023SJohn Marino 		continue;
5025e4b17023SJohn Marino 
5026e4b17023SJohn Marino 	      if (!live[pred])
5027e4b17023SJohn Marino 		{
5028e4b17023SJohn Marino 		  live[pred] = sbitmap_alloc (num_ssa_names);
5029e4b17023SJohn Marino 		  sbitmap_zero (live[pred]);
5030e4b17023SJohn Marino 		}
5031e4b17023SJohn Marino 	      sbitmap_a_or_b (live[pred], live[pred], live[rpo[i]]);
5032e4b17023SJohn Marino 
5033e4b17023SJohn Marino 	      if (bb_rpo[pred] < pred_rpo)
5034e4b17023SJohn Marino 		pred_rpo = bb_rpo[pred];
5035e4b17023SJohn Marino 	    }
5036e4b17023SJohn Marino 
5037e4b17023SJohn Marino 	  /* Record the RPO number of the last visited block that needs
5038e4b17023SJohn Marino 	     live information from this block.  */
5039e4b17023SJohn Marino 	  last_rpo[rpo[i]] = pred_rpo;
5040e4b17023SJohn Marino 	}
5041e4b17023SJohn Marino       else
5042e4b17023SJohn Marino 	{
5043e4b17023SJohn Marino 	  sbitmap_free (live[rpo[i]]);
5044e4b17023SJohn Marino 	  live[rpo[i]] = NULL;
5045e4b17023SJohn Marino 	}
5046e4b17023SJohn Marino 
5047e4b17023SJohn Marino       /* We can free all successors live bitmaps if all their
5048e4b17023SJohn Marino          predecessors have been visited already.  */
5049e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->succs)
5050e4b17023SJohn Marino 	if (last_rpo[e->dest->index] == i
5051e4b17023SJohn Marino 	    && live[e->dest->index])
5052e4b17023SJohn Marino 	  {
5053e4b17023SJohn Marino 	    sbitmap_free (live[e->dest->index]);
5054e4b17023SJohn Marino 	    live[e->dest->index] = NULL;
5055e4b17023SJohn Marino 	  }
5056e4b17023SJohn Marino     }
5057e4b17023SJohn Marino 
5058e4b17023SJohn Marino   XDELETEVEC (rpo);
5059e4b17023SJohn Marino   XDELETEVEC (bb_rpo);
5060e4b17023SJohn Marino   XDELETEVEC (last_rpo);
5061e4b17023SJohn Marino   for (i = 0; i < last_basic_block + NUM_FIXED_BLOCKS; ++i)
5062e4b17023SJohn Marino     if (live[i])
5063e4b17023SJohn Marino       sbitmap_free (live[i]);
5064e4b17023SJohn Marino   XDELETEVEC (live);
5065e4b17023SJohn Marino 
5066e4b17023SJohn Marino   return need_asserts;
5067e4b17023SJohn Marino }
5068e4b17023SJohn Marino 
5069e4b17023SJohn Marino /* Create an ASSERT_EXPR for NAME and insert it in the location
5070e4b17023SJohn Marino    indicated by LOC.  Return true if we made any edge insertions.  */
5071e4b17023SJohn Marino 
5072e4b17023SJohn Marino static bool
process_assert_insertions_for(tree name,assert_locus_t loc)5073e4b17023SJohn Marino process_assert_insertions_for (tree name, assert_locus_t loc)
5074e4b17023SJohn Marino {
5075e4b17023SJohn Marino   /* Build the comparison expression NAME_i COMP_CODE VAL.  */
5076e4b17023SJohn Marino   gimple stmt;
5077e4b17023SJohn Marino   tree cond;
5078e4b17023SJohn Marino   gimple assert_stmt;
5079e4b17023SJohn Marino   edge_iterator ei;
5080e4b17023SJohn Marino   edge e;
5081e4b17023SJohn Marino 
5082e4b17023SJohn Marino   /* If we have X <=> X do not insert an assert expr for that.  */
5083e4b17023SJohn Marino   if (loc->expr == loc->val)
5084e4b17023SJohn Marino     return false;
5085e4b17023SJohn Marino 
5086e4b17023SJohn Marino   cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc->val);
5087e4b17023SJohn Marino   assert_stmt = build_assert_expr_for (cond, name);
5088e4b17023SJohn Marino   if (loc->e)
5089e4b17023SJohn Marino     {
5090e4b17023SJohn Marino       /* We have been asked to insert the assertion on an edge.  This
5091e4b17023SJohn Marino 	 is used only by COND_EXPR and SWITCH_EXPR assertions.  */
5092e4b17023SJohn Marino       gcc_checking_assert (gimple_code (gsi_stmt (loc->si)) == GIMPLE_COND
5093e4b17023SJohn Marino 			   || (gimple_code (gsi_stmt (loc->si))
5094e4b17023SJohn Marino 			       == GIMPLE_SWITCH));
5095e4b17023SJohn Marino 
5096e4b17023SJohn Marino       gsi_insert_on_edge (loc->e, assert_stmt);
5097e4b17023SJohn Marino       return true;
5098e4b17023SJohn Marino     }
5099e4b17023SJohn Marino 
5100e4b17023SJohn Marino   /* Otherwise, we can insert right after LOC->SI iff the
5101e4b17023SJohn Marino      statement must not be the last statement in the block.  */
5102e4b17023SJohn Marino   stmt = gsi_stmt (loc->si);
5103e4b17023SJohn Marino   if (!stmt_ends_bb_p (stmt))
5104e4b17023SJohn Marino     {
5105e4b17023SJohn Marino       gsi_insert_after (&loc->si, assert_stmt, GSI_SAME_STMT);
5106e4b17023SJohn Marino       return false;
5107e4b17023SJohn Marino     }
5108e4b17023SJohn Marino 
5109e4b17023SJohn Marino   /* If STMT must be the last statement in BB, we can only insert new
5110e4b17023SJohn Marino      assertions on the non-abnormal edge out of BB.  Note that since
5111e4b17023SJohn Marino      STMT is not control flow, there may only be one non-abnormal edge
5112e4b17023SJohn Marino      out of BB.  */
5113e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, loc->bb->succs)
5114e4b17023SJohn Marino     if (!(e->flags & EDGE_ABNORMAL))
5115e4b17023SJohn Marino       {
5116e4b17023SJohn Marino 	gsi_insert_on_edge (e, assert_stmt);
5117e4b17023SJohn Marino 	return true;
5118e4b17023SJohn Marino       }
5119e4b17023SJohn Marino 
5120e4b17023SJohn Marino   gcc_unreachable ();
5121e4b17023SJohn Marino }
5122e4b17023SJohn Marino 
5123e4b17023SJohn Marino 
5124e4b17023SJohn Marino /* Process all the insertions registered for every name N_i registered
5125e4b17023SJohn Marino    in NEED_ASSERT_FOR.  The list of assertions to be inserted are
5126e4b17023SJohn Marino    found in ASSERTS_FOR[i].  */
5127e4b17023SJohn Marino 
5128e4b17023SJohn Marino static void
process_assert_insertions(void)5129e4b17023SJohn Marino process_assert_insertions (void)
5130e4b17023SJohn Marino {
5131e4b17023SJohn Marino   unsigned i;
5132e4b17023SJohn Marino   bitmap_iterator bi;
5133e4b17023SJohn Marino   bool update_edges_p = false;
5134e4b17023SJohn Marino   int num_asserts = 0;
5135e4b17023SJohn Marino 
5136e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
5137e4b17023SJohn Marino     dump_all_asserts (dump_file);
5138e4b17023SJohn Marino 
5139e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
5140e4b17023SJohn Marino     {
5141e4b17023SJohn Marino       assert_locus_t loc = asserts_for[i];
5142e4b17023SJohn Marino       gcc_assert (loc);
5143e4b17023SJohn Marino 
5144e4b17023SJohn Marino       while (loc)
5145e4b17023SJohn Marino 	{
5146e4b17023SJohn Marino 	  assert_locus_t next = loc->next;
5147e4b17023SJohn Marino 	  update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
5148e4b17023SJohn Marino 	  free (loc);
5149e4b17023SJohn Marino 	  loc = next;
5150e4b17023SJohn Marino 	  num_asserts++;
5151e4b17023SJohn Marino 	}
5152e4b17023SJohn Marino     }
5153e4b17023SJohn Marino 
5154e4b17023SJohn Marino   if (update_edges_p)
5155e4b17023SJohn Marino     gsi_commit_edge_inserts ();
5156e4b17023SJohn Marino 
5157e4b17023SJohn Marino   statistics_counter_event (cfun, "Number of ASSERT_EXPR expressions inserted",
5158e4b17023SJohn Marino 			    num_asserts);
5159e4b17023SJohn Marino }
5160e4b17023SJohn Marino 
5161e4b17023SJohn Marino 
5162e4b17023SJohn Marino /* Traverse the flowgraph looking for conditional jumps to insert range
5163e4b17023SJohn Marino    expressions.  These range expressions are meant to provide information
5164e4b17023SJohn Marino    to optimizations that need to reason in terms of value ranges.  They
5165e4b17023SJohn Marino    will not be expanded into RTL.  For instance, given:
5166e4b17023SJohn Marino 
5167e4b17023SJohn Marino    x = ...
5168e4b17023SJohn Marino    y = ...
5169e4b17023SJohn Marino    if (x < y)
5170e4b17023SJohn Marino      y = x - 2;
5171e4b17023SJohn Marino    else
5172e4b17023SJohn Marino      x = y + 3;
5173e4b17023SJohn Marino 
5174e4b17023SJohn Marino    this pass will transform the code into:
5175e4b17023SJohn Marino 
5176e4b17023SJohn Marino    x = ...
5177e4b17023SJohn Marino    y = ...
5178e4b17023SJohn Marino    if (x < y)
5179e4b17023SJohn Marino     {
5180e4b17023SJohn Marino       x = ASSERT_EXPR <x, x < y>
5181e4b17023SJohn Marino       y = x - 2
5182e4b17023SJohn Marino     }
5183e4b17023SJohn Marino    else
5184e4b17023SJohn Marino     {
5185e4b17023SJohn Marino       y = ASSERT_EXPR <y, x <= y>
5186e4b17023SJohn Marino       x = y + 3
5187e4b17023SJohn Marino     }
5188e4b17023SJohn Marino 
5189e4b17023SJohn Marino    The idea is that once copy and constant propagation have run, other
5190e4b17023SJohn Marino    optimizations will be able to determine what ranges of values can 'x'
5191e4b17023SJohn Marino    take in different paths of the code, simply by checking the reaching
5192e4b17023SJohn Marino    definition of 'x'.  */
5193e4b17023SJohn Marino 
5194e4b17023SJohn Marino static void
insert_range_assertions(void)5195e4b17023SJohn Marino insert_range_assertions (void)
5196e4b17023SJohn Marino {
5197e4b17023SJohn Marino   need_assert_for = BITMAP_ALLOC (NULL);
5198e4b17023SJohn Marino   asserts_for = XCNEWVEC (assert_locus_t, num_ssa_names);
5199e4b17023SJohn Marino 
5200e4b17023SJohn Marino   calculate_dominance_info (CDI_DOMINATORS);
5201e4b17023SJohn Marino 
5202e4b17023SJohn Marino   if (find_assert_locations ())
5203e4b17023SJohn Marino     {
5204e4b17023SJohn Marino       process_assert_insertions ();
5205e4b17023SJohn Marino       update_ssa (TODO_update_ssa_no_phi);
5206e4b17023SJohn Marino     }
5207e4b17023SJohn Marino 
5208e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
5209e4b17023SJohn Marino     {
5210e4b17023SJohn Marino       fprintf (dump_file, "\nSSA form after inserting ASSERT_EXPRs\n");
5211e4b17023SJohn Marino       dump_function_to_file (current_function_decl, dump_file, dump_flags);
5212e4b17023SJohn Marino     }
5213e4b17023SJohn Marino 
5214e4b17023SJohn Marino   free (asserts_for);
5215e4b17023SJohn Marino   BITMAP_FREE (need_assert_for);
5216e4b17023SJohn Marino }
5217e4b17023SJohn Marino 
5218e4b17023SJohn Marino /* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
5219e4b17023SJohn Marino    and "struct" hacks. If VRP can determine that the
5220e4b17023SJohn Marino    array subscript is a constant, check if it is outside valid
5221e4b17023SJohn Marino    range. If the array subscript is a RANGE, warn if it is
5222e4b17023SJohn Marino    non-overlapping with valid range.
5223e4b17023SJohn Marino    IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR.  */
5224e4b17023SJohn Marino 
5225e4b17023SJohn Marino static void
check_array_ref(location_t location,tree ref,bool ignore_off_by_one)5226e4b17023SJohn Marino check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
5227e4b17023SJohn Marino {
5228e4b17023SJohn Marino   value_range_t* vr = NULL;
5229e4b17023SJohn Marino   tree low_sub, up_sub;
5230e4b17023SJohn Marino   tree low_bound, up_bound, up_bound_p1;
5231e4b17023SJohn Marino   tree base;
5232e4b17023SJohn Marino 
5233e4b17023SJohn Marino   if (TREE_NO_WARNING (ref))
5234e4b17023SJohn Marino     return;
5235e4b17023SJohn Marino 
5236e4b17023SJohn Marino   low_sub = up_sub = TREE_OPERAND (ref, 1);
5237e4b17023SJohn Marino   up_bound = array_ref_up_bound (ref);
5238e4b17023SJohn Marino 
5239e4b17023SJohn Marino   /* Can not check flexible arrays.  */
5240e4b17023SJohn Marino   if (!up_bound
5241e4b17023SJohn Marino       || TREE_CODE (up_bound) != INTEGER_CST)
5242e4b17023SJohn Marino     return;
5243e4b17023SJohn Marino 
5244e4b17023SJohn Marino   /* Accesses to trailing arrays via pointers may access storage
5245e4b17023SJohn Marino      beyond the types array bounds.  */
5246e4b17023SJohn Marino   base = get_base_address (ref);
5247e4b17023SJohn Marino   if (base && TREE_CODE (base) == MEM_REF)
5248e4b17023SJohn Marino     {
5249e4b17023SJohn Marino       tree cref, next = NULL_TREE;
5250e4b17023SJohn Marino 
5251e4b17023SJohn Marino       if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF)
5252e4b17023SJohn Marino 	return;
5253e4b17023SJohn Marino 
5254e4b17023SJohn Marino       cref = TREE_OPERAND (ref, 0);
5255e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
5256e4b17023SJohn Marino 	for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
5257e4b17023SJohn Marino 	     next && TREE_CODE (next) != FIELD_DECL;
5258e4b17023SJohn Marino 	     next = DECL_CHAIN (next))
5259e4b17023SJohn Marino 	  ;
5260e4b17023SJohn Marino 
5261e4b17023SJohn Marino       /* If this is the last field in a struct type or a field in a
5262e4b17023SJohn Marino 	 union type do not warn.  */
5263e4b17023SJohn Marino       if (!next)
5264e4b17023SJohn Marino 	return;
5265e4b17023SJohn Marino     }
5266e4b17023SJohn Marino 
5267e4b17023SJohn Marino   low_bound = array_ref_low_bound (ref);
5268e4b17023SJohn Marino   up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, integer_one_node);
5269e4b17023SJohn Marino 
5270e4b17023SJohn Marino   if (TREE_CODE (low_sub) == SSA_NAME)
5271e4b17023SJohn Marino     {
5272e4b17023SJohn Marino       vr = get_value_range (low_sub);
5273e4b17023SJohn Marino       if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
5274e4b17023SJohn Marino         {
5275e4b17023SJohn Marino           low_sub = vr->type == VR_RANGE ? vr->max : vr->min;
5276e4b17023SJohn Marino           up_sub = vr->type == VR_RANGE ? vr->min : vr->max;
5277e4b17023SJohn Marino         }
5278e4b17023SJohn Marino     }
5279e4b17023SJohn Marino 
5280e4b17023SJohn Marino   if (vr && vr->type == VR_ANTI_RANGE)
5281e4b17023SJohn Marino     {
5282e4b17023SJohn Marino       if (TREE_CODE (up_sub) == INTEGER_CST
5283e4b17023SJohn Marino           && tree_int_cst_lt (up_bound, up_sub)
5284e4b17023SJohn Marino           && TREE_CODE (low_sub) == INTEGER_CST
5285e4b17023SJohn Marino           && tree_int_cst_lt (low_sub, low_bound))
5286e4b17023SJohn Marino         {
5287e4b17023SJohn Marino           warning_at (location, OPT_Warray_bounds,
5288e4b17023SJohn Marino 		      "array subscript is outside array bounds");
5289e4b17023SJohn Marino           TREE_NO_WARNING (ref) = 1;
5290e4b17023SJohn Marino         }
5291e4b17023SJohn Marino     }
5292e4b17023SJohn Marino   else if (TREE_CODE (up_sub) == INTEGER_CST
5293e4b17023SJohn Marino 	   && (ignore_off_by_one
5294e4b17023SJohn Marino 	       ? (tree_int_cst_lt (up_bound, up_sub)
5295e4b17023SJohn Marino 		  && !tree_int_cst_equal (up_bound_p1, up_sub))
5296e4b17023SJohn Marino 	       : (tree_int_cst_lt (up_bound, up_sub)
5297e4b17023SJohn Marino 		  || tree_int_cst_equal (up_bound_p1, up_sub))))
5298e4b17023SJohn Marino     {
5299e4b17023SJohn Marino       warning_at (location, OPT_Warray_bounds,
5300e4b17023SJohn Marino 		  "array subscript is above array bounds");
5301e4b17023SJohn Marino       TREE_NO_WARNING (ref) = 1;
5302e4b17023SJohn Marino     }
5303e4b17023SJohn Marino   else if (TREE_CODE (low_sub) == INTEGER_CST
5304e4b17023SJohn Marino            && tree_int_cst_lt (low_sub, low_bound))
5305e4b17023SJohn Marino     {
5306e4b17023SJohn Marino       warning_at (location, OPT_Warray_bounds,
5307e4b17023SJohn Marino 		  "array subscript is below array bounds");
5308e4b17023SJohn Marino       TREE_NO_WARNING (ref) = 1;
5309e4b17023SJohn Marino     }
5310e4b17023SJohn Marino }
5311e4b17023SJohn Marino 
5312e4b17023SJohn Marino /* Searches if the expr T, located at LOCATION computes
5313e4b17023SJohn Marino    address of an ARRAY_REF, and call check_array_ref on it.  */
5314e4b17023SJohn Marino 
5315e4b17023SJohn Marino static void
search_for_addr_array(tree t,location_t location)5316e4b17023SJohn Marino search_for_addr_array (tree t, location_t location)
5317e4b17023SJohn Marino {
5318e4b17023SJohn Marino   while (TREE_CODE (t) == SSA_NAME)
5319e4b17023SJohn Marino     {
5320e4b17023SJohn Marino       gimple g = SSA_NAME_DEF_STMT (t);
5321e4b17023SJohn Marino 
5322e4b17023SJohn Marino       if (gimple_code (g) != GIMPLE_ASSIGN)
5323e4b17023SJohn Marino 	return;
5324e4b17023SJohn Marino 
5325e4b17023SJohn Marino       if (get_gimple_rhs_class (gimple_assign_rhs_code (g))
5326e4b17023SJohn Marino 	  != GIMPLE_SINGLE_RHS)
5327e4b17023SJohn Marino 	return;
5328e4b17023SJohn Marino 
5329e4b17023SJohn Marino       t = gimple_assign_rhs1 (g);
5330e4b17023SJohn Marino     }
5331e4b17023SJohn Marino 
5332e4b17023SJohn Marino 
5333e4b17023SJohn Marino   /* We are only interested in addresses of ARRAY_REF's.  */
5334e4b17023SJohn Marino   if (TREE_CODE (t) != ADDR_EXPR)
5335e4b17023SJohn Marino     return;
5336e4b17023SJohn Marino 
5337e4b17023SJohn Marino   /* Check each ARRAY_REFs in the reference chain. */
5338e4b17023SJohn Marino   do
5339e4b17023SJohn Marino     {
5340e4b17023SJohn Marino       if (TREE_CODE (t) == ARRAY_REF)
5341e4b17023SJohn Marino 	check_array_ref (location, t, true /*ignore_off_by_one*/);
5342e4b17023SJohn Marino 
5343e4b17023SJohn Marino       t = TREE_OPERAND (t, 0);
5344e4b17023SJohn Marino     }
5345e4b17023SJohn Marino   while (handled_component_p (t));
5346e4b17023SJohn Marino 
5347e4b17023SJohn Marino   if (TREE_CODE (t) == MEM_REF
5348e4b17023SJohn Marino       && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
5349e4b17023SJohn Marino       && !TREE_NO_WARNING (t))
5350e4b17023SJohn Marino     {
5351e4b17023SJohn Marino       tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
5352e4b17023SJohn Marino       tree low_bound, up_bound, el_sz;
5353e4b17023SJohn Marino       double_int idx;
5354e4b17023SJohn Marino       if (TREE_CODE (TREE_TYPE (tem)) != ARRAY_TYPE
5355e4b17023SJohn Marino 	  || TREE_CODE (TREE_TYPE (TREE_TYPE (tem))) == ARRAY_TYPE
5356e4b17023SJohn Marino 	  || !TYPE_DOMAIN (TREE_TYPE (tem)))
5357e4b17023SJohn Marino 	return;
5358e4b17023SJohn Marino 
5359e4b17023SJohn Marino       low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (tem)));
5360e4b17023SJohn Marino       up_bound = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tem)));
5361e4b17023SJohn Marino       el_sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (tem)));
5362e4b17023SJohn Marino       if (!low_bound
5363e4b17023SJohn Marino 	  || TREE_CODE (low_bound) != INTEGER_CST
5364e4b17023SJohn Marino 	  || !up_bound
5365e4b17023SJohn Marino 	  || TREE_CODE (up_bound) != INTEGER_CST
5366e4b17023SJohn Marino 	  || !el_sz
5367e4b17023SJohn Marino 	  || TREE_CODE (el_sz) != INTEGER_CST)
5368e4b17023SJohn Marino 	return;
5369e4b17023SJohn Marino 
5370e4b17023SJohn Marino       idx = mem_ref_offset (t);
5371e4b17023SJohn Marino       idx = double_int_sdiv (idx, tree_to_double_int (el_sz), TRUNC_DIV_EXPR);
5372e4b17023SJohn Marino       if (double_int_scmp (idx, double_int_zero) < 0)
5373e4b17023SJohn Marino 	{
5374e4b17023SJohn Marino 	  warning_at (location, OPT_Warray_bounds,
5375e4b17023SJohn Marino 		      "array subscript is below array bounds");
5376e4b17023SJohn Marino 	  TREE_NO_WARNING (t) = 1;
5377e4b17023SJohn Marino 	}
5378e4b17023SJohn Marino       else if (double_int_scmp (idx,
5379e4b17023SJohn Marino 				double_int_add
5380e4b17023SJohn Marino 				  (double_int_add
5381e4b17023SJohn Marino 				    (tree_to_double_int (up_bound),
5382e4b17023SJohn Marino 				     double_int_neg
5383e4b17023SJohn Marino 				       (tree_to_double_int (low_bound))),
5384e4b17023SJohn Marino 				    double_int_one)) > 0)
5385e4b17023SJohn Marino 	{
5386e4b17023SJohn Marino 	  warning_at (location, OPT_Warray_bounds,
5387e4b17023SJohn Marino 		      "array subscript is above array bounds");
5388e4b17023SJohn Marino 	  TREE_NO_WARNING (t) = 1;
5389e4b17023SJohn Marino 	}
5390e4b17023SJohn Marino     }
5391e4b17023SJohn Marino }
5392e4b17023SJohn Marino 
5393e4b17023SJohn Marino /* walk_tree() callback that checks if *TP is
5394e4b17023SJohn Marino    an ARRAY_REF inside an ADDR_EXPR (in which an array
5395e4b17023SJohn Marino    subscript one outside the valid range is allowed). Call
5396e4b17023SJohn Marino    check_array_ref for each ARRAY_REF found. The location is
5397e4b17023SJohn Marino    passed in DATA.  */
5398e4b17023SJohn Marino 
5399e4b17023SJohn Marino static tree
check_array_bounds(tree * tp,int * walk_subtree,void * data)5400e4b17023SJohn Marino check_array_bounds (tree *tp, int *walk_subtree, void *data)
5401e4b17023SJohn Marino {
5402e4b17023SJohn Marino   tree t = *tp;
5403e4b17023SJohn Marino   struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
5404e4b17023SJohn Marino   location_t location;
5405e4b17023SJohn Marino 
5406e4b17023SJohn Marino   if (EXPR_HAS_LOCATION (t))
5407e4b17023SJohn Marino     location = EXPR_LOCATION (t);
5408e4b17023SJohn Marino   else
5409e4b17023SJohn Marino     {
5410e4b17023SJohn Marino       location_t *locp = (location_t *) wi->info;
5411e4b17023SJohn Marino       location = *locp;
5412e4b17023SJohn Marino     }
5413e4b17023SJohn Marino 
5414e4b17023SJohn Marino   *walk_subtree = TRUE;
5415e4b17023SJohn Marino 
5416e4b17023SJohn Marino   if (TREE_CODE (t) == ARRAY_REF)
5417e4b17023SJohn Marino     check_array_ref (location, t, false /*ignore_off_by_one*/);
5418e4b17023SJohn Marino 
5419e4b17023SJohn Marino   if (TREE_CODE (t) == MEM_REF
5420e4b17023SJohn Marino       || (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
5421e4b17023SJohn Marino     search_for_addr_array (TREE_OPERAND (t, 0), location);
5422e4b17023SJohn Marino 
5423e4b17023SJohn Marino   if (TREE_CODE (t) == ADDR_EXPR)
5424e4b17023SJohn Marino     *walk_subtree = FALSE;
5425e4b17023SJohn Marino 
5426e4b17023SJohn Marino   return NULL_TREE;
5427e4b17023SJohn Marino }
5428e4b17023SJohn Marino 
5429e4b17023SJohn Marino /* Walk over all statements of all reachable BBs and call check_array_bounds
5430e4b17023SJohn Marino    on them.  */
5431e4b17023SJohn Marino 
5432e4b17023SJohn Marino static void
check_all_array_refs(void)5433e4b17023SJohn Marino check_all_array_refs (void)
5434e4b17023SJohn Marino {
5435e4b17023SJohn Marino   basic_block bb;
5436e4b17023SJohn Marino   gimple_stmt_iterator si;
5437e4b17023SJohn Marino 
5438e4b17023SJohn Marino   FOR_EACH_BB (bb)
5439e4b17023SJohn Marino     {
5440e4b17023SJohn Marino       edge_iterator ei;
5441e4b17023SJohn Marino       edge e;
5442e4b17023SJohn Marino       bool executable = false;
5443e4b17023SJohn Marino 
5444e4b17023SJohn Marino       /* Skip blocks that were found to be unreachable.  */
5445e4b17023SJohn Marino       FOR_EACH_EDGE (e, ei, bb->preds)
5446e4b17023SJohn Marino 	executable |= !!(e->flags & EDGE_EXECUTABLE);
5447e4b17023SJohn Marino       if (!executable)
5448e4b17023SJohn Marino 	continue;
5449e4b17023SJohn Marino 
5450e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
5451e4b17023SJohn Marino 	{
5452e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (si);
5453e4b17023SJohn Marino 	  struct walk_stmt_info wi;
5454e4b17023SJohn Marino 	  if (!gimple_has_location (stmt))
5455e4b17023SJohn Marino 	    continue;
5456e4b17023SJohn Marino 
5457e4b17023SJohn Marino 	  if (is_gimple_call (stmt))
5458e4b17023SJohn Marino 	    {
5459e4b17023SJohn Marino 	      size_t i;
5460e4b17023SJohn Marino 	      size_t n = gimple_call_num_args (stmt);
5461e4b17023SJohn Marino 	      for (i = 0; i < n; i++)
5462e4b17023SJohn Marino 		{
5463e4b17023SJohn Marino 		  tree arg = gimple_call_arg (stmt, i);
5464e4b17023SJohn Marino 		  search_for_addr_array (arg, gimple_location (stmt));
5465e4b17023SJohn Marino 		}
5466e4b17023SJohn Marino 	    }
5467e4b17023SJohn Marino 	  else
5468e4b17023SJohn Marino 	    {
5469e4b17023SJohn Marino 	      memset (&wi, 0, sizeof (wi));
5470e4b17023SJohn Marino 	      wi.info = CONST_CAST (void *, (const void *)
5471e4b17023SJohn Marino 				    gimple_location_ptr (stmt));
5472e4b17023SJohn Marino 
5473e4b17023SJohn Marino 	      walk_gimple_op (gsi_stmt (si),
5474e4b17023SJohn Marino 			      check_array_bounds,
5475e4b17023SJohn Marino 			      &wi);
5476e4b17023SJohn Marino 	    }
5477e4b17023SJohn Marino 	}
5478e4b17023SJohn Marino     }
5479e4b17023SJohn Marino }
5480e4b17023SJohn Marino 
5481e4b17023SJohn Marino /* Convert range assertion expressions into the implied copies and
5482e4b17023SJohn Marino    copy propagate away the copies.  Doing the trivial copy propagation
5483e4b17023SJohn Marino    here avoids the need to run the full copy propagation pass after
5484e4b17023SJohn Marino    VRP.
5485e4b17023SJohn Marino 
5486e4b17023SJohn Marino    FIXME, this will eventually lead to copy propagation removing the
5487e4b17023SJohn Marino    names that had useful range information attached to them.  For
5488e4b17023SJohn Marino    instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
5489e4b17023SJohn Marino    then N_i will have the range [3, +INF].
5490e4b17023SJohn Marino 
5491e4b17023SJohn Marino    However, by converting the assertion into the implied copy
5492e4b17023SJohn Marino    operation N_i = N_j, we will then copy-propagate N_j into the uses
5493e4b17023SJohn Marino    of N_i and lose the range information.  We may want to hold on to
5494e4b17023SJohn Marino    ASSERT_EXPRs a little while longer as the ranges could be used in
5495e4b17023SJohn Marino    things like jump threading.
5496e4b17023SJohn Marino 
5497e4b17023SJohn Marino    The problem with keeping ASSERT_EXPRs around is that passes after
5498e4b17023SJohn Marino    VRP need to handle them appropriately.
5499e4b17023SJohn Marino 
5500e4b17023SJohn Marino    Another approach would be to make the range information a first
5501e4b17023SJohn Marino    class property of the SSA_NAME so that it can be queried from
5502e4b17023SJohn Marino    any pass.  This is made somewhat more complex by the need for
5503e4b17023SJohn Marino    multiple ranges to be associated with one SSA_NAME.  */
5504e4b17023SJohn Marino 
5505e4b17023SJohn Marino static void
remove_range_assertions(void)5506e4b17023SJohn Marino remove_range_assertions (void)
5507e4b17023SJohn Marino {
5508e4b17023SJohn Marino   basic_block bb;
5509e4b17023SJohn Marino   gimple_stmt_iterator si;
5510e4b17023SJohn Marino 
5511e4b17023SJohn Marino   /* Note that the BSI iterator bump happens at the bottom of the
5512e4b17023SJohn Marino      loop and no bump is necessary if we're removing the statement
5513e4b17023SJohn Marino      referenced by the current BSI.  */
5514e4b17023SJohn Marino   FOR_EACH_BB (bb)
5515e4b17023SJohn Marino     for (si = gsi_start_bb (bb); !gsi_end_p (si);)
5516e4b17023SJohn Marino       {
5517e4b17023SJohn Marino 	gimple stmt = gsi_stmt (si);
5518e4b17023SJohn Marino 	gimple use_stmt;
5519e4b17023SJohn Marino 
5520e4b17023SJohn Marino 	if (is_gimple_assign (stmt)
5521e4b17023SJohn Marino 	    && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
5522e4b17023SJohn Marino 	  {
5523e4b17023SJohn Marino 	    tree rhs = gimple_assign_rhs1 (stmt);
5524e4b17023SJohn Marino 	    tree var;
5525e4b17023SJohn Marino 	    tree cond = fold (ASSERT_EXPR_COND (rhs));
5526e4b17023SJohn Marino 	    use_operand_p use_p;
5527e4b17023SJohn Marino 	    imm_use_iterator iter;
5528e4b17023SJohn Marino 
5529e4b17023SJohn Marino 	    gcc_assert (cond != boolean_false_node);
5530e4b17023SJohn Marino 
5531e4b17023SJohn Marino 	    /* Propagate the RHS into every use of the LHS.  */
5532e4b17023SJohn Marino 	    var = ASSERT_EXPR_VAR (rhs);
5533e4b17023SJohn Marino 	    FOR_EACH_IMM_USE_STMT (use_stmt, iter,
5534e4b17023SJohn Marino 				   gimple_assign_lhs (stmt))
5535e4b17023SJohn Marino 	      FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
5536e4b17023SJohn Marino 		{
5537e4b17023SJohn Marino 		  SET_USE (use_p, var);
5538e4b17023SJohn Marino 		  gcc_assert (TREE_CODE (var) == SSA_NAME);
5539e4b17023SJohn Marino 		}
5540e4b17023SJohn Marino 
5541e4b17023SJohn Marino 	    /* And finally, remove the copy, it is not needed.  */
5542e4b17023SJohn Marino 	    gsi_remove (&si, true);
5543e4b17023SJohn Marino 	    release_defs (stmt);
5544e4b17023SJohn Marino 	  }
5545e4b17023SJohn Marino 	else
5546e4b17023SJohn Marino 	  gsi_next (&si);
5547e4b17023SJohn Marino       }
5548e4b17023SJohn Marino }
5549e4b17023SJohn Marino 
5550e4b17023SJohn Marino 
5551e4b17023SJohn Marino /* Return true if STMT is interesting for VRP.  */
5552e4b17023SJohn Marino 
5553e4b17023SJohn Marino static bool
stmt_interesting_for_vrp(gimple stmt)5554e4b17023SJohn Marino stmt_interesting_for_vrp (gimple stmt)
5555e4b17023SJohn Marino {
5556e4b17023SJohn Marino   if (gimple_code (stmt) == GIMPLE_PHI
5557e4b17023SJohn Marino       && is_gimple_reg (gimple_phi_result (stmt))
5558e4b17023SJohn Marino       && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))
5559e4b17023SJohn Marino 	  || POINTER_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))))
5560e4b17023SJohn Marino     return true;
5561e4b17023SJohn Marino   else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
5562e4b17023SJohn Marino     {
5563e4b17023SJohn Marino       tree lhs = gimple_get_lhs (stmt);
5564e4b17023SJohn Marino 
5565e4b17023SJohn Marino       /* In general, assignments with virtual operands are not useful
5566e4b17023SJohn Marino 	 for deriving ranges, with the obvious exception of calls to
5567e4b17023SJohn Marino 	 builtin functions.  */
5568e4b17023SJohn Marino       if (lhs && TREE_CODE (lhs) == SSA_NAME
5569e4b17023SJohn Marino 	  && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
5570e4b17023SJohn Marino 	      || POINTER_TYPE_P (TREE_TYPE (lhs)))
5571e4b17023SJohn Marino 	  && ((is_gimple_call (stmt)
5572e4b17023SJohn Marino 	       && gimple_call_fndecl (stmt) != NULL_TREE
5573e4b17023SJohn Marino 	       && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
5574e4b17023SJohn Marino 	      || !gimple_vuse (stmt)))
5575e4b17023SJohn Marino 	return true;
5576e4b17023SJohn Marino     }
5577e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_COND
5578e4b17023SJohn Marino 	   || gimple_code (stmt) == GIMPLE_SWITCH)
5579e4b17023SJohn Marino     return true;
5580e4b17023SJohn Marino 
5581e4b17023SJohn Marino   return false;
5582e4b17023SJohn Marino }
5583e4b17023SJohn Marino 
5584e4b17023SJohn Marino 
5585e4b17023SJohn Marino /* Initialize local data structures for VRP.  */
5586e4b17023SJohn Marino 
5587e4b17023SJohn Marino static void
vrp_initialize(void)5588e4b17023SJohn Marino vrp_initialize (void)
5589e4b17023SJohn Marino {
5590e4b17023SJohn Marino   basic_block bb;
5591e4b17023SJohn Marino 
5592e4b17023SJohn Marino   values_propagated = false;
5593e4b17023SJohn Marino   num_vr_values = num_ssa_names;
5594e4b17023SJohn Marino   vr_value = XCNEWVEC (value_range_t *, num_vr_values);
5595e4b17023SJohn Marino   vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
5596e4b17023SJohn Marino 
5597e4b17023SJohn Marino   FOR_EACH_BB (bb)
5598e4b17023SJohn Marino     {
5599e4b17023SJohn Marino       gimple_stmt_iterator si;
5600e4b17023SJohn Marino 
5601e4b17023SJohn Marino       for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
5602e4b17023SJohn Marino 	{
5603e4b17023SJohn Marino 	  gimple phi = gsi_stmt (si);
5604e4b17023SJohn Marino 	  if (!stmt_interesting_for_vrp (phi))
5605e4b17023SJohn Marino 	    {
5606e4b17023SJohn Marino 	      tree lhs = PHI_RESULT (phi);
5607e4b17023SJohn Marino 	      set_value_range_to_varying (get_value_range (lhs));
5608e4b17023SJohn Marino 	      prop_set_simulate_again (phi, false);
5609e4b17023SJohn Marino 	    }
5610e4b17023SJohn Marino 	  else
5611e4b17023SJohn Marino 	    prop_set_simulate_again (phi, true);
5612e4b17023SJohn Marino 	}
5613e4b17023SJohn Marino 
5614e4b17023SJohn Marino       for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
5615e4b17023SJohn Marino         {
5616e4b17023SJohn Marino 	  gimple stmt = gsi_stmt (si);
5617e4b17023SJohn Marino 
5618e4b17023SJohn Marino  	  /* If the statement is a control insn, then we do not
5619e4b17023SJohn Marino  	     want to avoid simulating the statement once.  Failure
5620e4b17023SJohn Marino  	     to do so means that those edges will never get added.  */
5621e4b17023SJohn Marino 	  if (stmt_ends_bb_p (stmt))
5622e4b17023SJohn Marino 	    prop_set_simulate_again (stmt, true);
5623e4b17023SJohn Marino 	  else if (!stmt_interesting_for_vrp (stmt))
5624e4b17023SJohn Marino 	    {
5625e4b17023SJohn Marino 	      ssa_op_iter i;
5626e4b17023SJohn Marino 	      tree def;
5627e4b17023SJohn Marino 	      FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
5628e4b17023SJohn Marino 		set_value_range_to_varying (get_value_range (def));
5629e4b17023SJohn Marino 	      prop_set_simulate_again (stmt, false);
5630e4b17023SJohn Marino 	    }
5631e4b17023SJohn Marino 	  else
5632e4b17023SJohn Marino 	    prop_set_simulate_again (stmt, true);
5633e4b17023SJohn Marino 	}
5634e4b17023SJohn Marino     }
5635e4b17023SJohn Marino }
5636e4b17023SJohn Marino 
5637e4b17023SJohn Marino /* Return the singleton value-range for NAME or NAME.  */
5638e4b17023SJohn Marino 
5639e4b17023SJohn Marino static inline tree
vrp_valueize(tree name)5640e4b17023SJohn Marino vrp_valueize (tree name)
5641e4b17023SJohn Marino {
5642e4b17023SJohn Marino   if (TREE_CODE (name) == SSA_NAME)
5643e4b17023SJohn Marino     {
5644e4b17023SJohn Marino       value_range_t *vr = get_value_range (name);
5645e4b17023SJohn Marino       if (vr->type == VR_RANGE
5646e4b17023SJohn Marino 	  && (vr->min == vr->max
5647e4b17023SJohn Marino 	      || operand_equal_p (vr->min, vr->max, 0)))
5648e4b17023SJohn Marino 	return vr->min;
5649e4b17023SJohn Marino     }
5650e4b17023SJohn Marino   return name;
5651e4b17023SJohn Marino }
5652e4b17023SJohn Marino 
5653e4b17023SJohn Marino /* Visit assignment STMT.  If it produces an interesting range, record
5654e4b17023SJohn Marino    the SSA name in *OUTPUT_P.  */
5655e4b17023SJohn Marino 
5656e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_assignment_or_call(gimple stmt,tree * output_p)5657e4b17023SJohn Marino vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
5658e4b17023SJohn Marino {
5659e4b17023SJohn Marino   tree def, lhs;
5660e4b17023SJohn Marino   ssa_op_iter iter;
5661e4b17023SJohn Marino   enum gimple_code code = gimple_code (stmt);
5662e4b17023SJohn Marino   lhs = gimple_get_lhs (stmt);
5663e4b17023SJohn Marino 
5664e4b17023SJohn Marino   /* We only keep track of ranges in integral and pointer types.  */
5665e4b17023SJohn Marino   if (TREE_CODE (lhs) == SSA_NAME
5666e4b17023SJohn Marino       && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
5667e4b17023SJohn Marino 	   /* It is valid to have NULL MIN/MAX values on a type.  See
5668e4b17023SJohn Marino 	      build_range_type.  */
5669e4b17023SJohn Marino 	   && TYPE_MIN_VALUE (TREE_TYPE (lhs))
5670e4b17023SJohn Marino 	   && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
5671e4b17023SJohn Marino 	  || POINTER_TYPE_P (TREE_TYPE (lhs))))
5672e4b17023SJohn Marino     {
5673e4b17023SJohn Marino       value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
5674e4b17023SJohn Marino 
5675e4b17023SJohn Marino       /* Try folding the statement to a constant first.  */
5676e4b17023SJohn Marino       tree tem = gimple_fold_stmt_to_constant (stmt, vrp_valueize);
5677e4b17023SJohn Marino       if (tem && !is_overflow_infinity (tem))
5678e4b17023SJohn Marino 	set_value_range (&new_vr, VR_RANGE, tem, tem, NULL);
5679e4b17023SJohn Marino       /* Then dispatch to value-range extracting functions.  */
5680e4b17023SJohn Marino       else if (code == GIMPLE_CALL)
5681e4b17023SJohn Marino 	extract_range_basic (&new_vr, stmt);
5682e4b17023SJohn Marino       else
5683e4b17023SJohn Marino 	extract_range_from_assignment (&new_vr, stmt);
5684e4b17023SJohn Marino 
5685e4b17023SJohn Marino       if (update_value_range (lhs, &new_vr))
5686e4b17023SJohn Marino 	{
5687e4b17023SJohn Marino 	  *output_p = lhs;
5688e4b17023SJohn Marino 
5689e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
5690e4b17023SJohn Marino 	    {
5691e4b17023SJohn Marino 	      fprintf (dump_file, "Found new range for ");
5692e4b17023SJohn Marino 	      print_generic_expr (dump_file, lhs, 0);
5693e4b17023SJohn Marino 	      fprintf (dump_file, ": ");
5694e4b17023SJohn Marino 	      dump_value_range (dump_file, &new_vr);
5695e4b17023SJohn Marino 	      fprintf (dump_file, "\n\n");
5696e4b17023SJohn Marino 	    }
5697e4b17023SJohn Marino 
5698e4b17023SJohn Marino 	  if (new_vr.type == VR_VARYING)
5699e4b17023SJohn Marino 	    return SSA_PROP_VARYING;
5700e4b17023SJohn Marino 
5701e4b17023SJohn Marino 	  return SSA_PROP_INTERESTING;
5702e4b17023SJohn Marino 	}
5703e4b17023SJohn Marino 
5704e4b17023SJohn Marino       return SSA_PROP_NOT_INTERESTING;
5705e4b17023SJohn Marino     }
5706e4b17023SJohn Marino 
5707e4b17023SJohn Marino   /* Every other statement produces no useful ranges.  */
5708e4b17023SJohn Marino   FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
5709e4b17023SJohn Marino     set_value_range_to_varying (get_value_range (def));
5710e4b17023SJohn Marino 
5711e4b17023SJohn Marino   return SSA_PROP_VARYING;
5712e4b17023SJohn Marino }
5713e4b17023SJohn Marino 
5714e4b17023SJohn Marino /* Helper that gets the value range of the SSA_NAME with version I
5715e4b17023SJohn Marino    or a symbolic range containing the SSA_NAME only if the value range
5716e4b17023SJohn Marino    is varying or undefined.  */
5717e4b17023SJohn Marino 
5718e4b17023SJohn Marino static inline value_range_t
get_vr_for_comparison(int i)5719e4b17023SJohn Marino get_vr_for_comparison (int i)
5720e4b17023SJohn Marino {
5721e4b17023SJohn Marino   value_range_t vr = *get_value_range (ssa_name (i));
5722e4b17023SJohn Marino 
5723e4b17023SJohn Marino   /* If name N_i does not have a valid range, use N_i as its own
5724e4b17023SJohn Marino      range.  This allows us to compare against names that may
5725e4b17023SJohn Marino      have N_i in their ranges.  */
5726e4b17023SJohn Marino   if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
5727e4b17023SJohn Marino     {
5728e4b17023SJohn Marino       vr.type = VR_RANGE;
5729e4b17023SJohn Marino       vr.min = ssa_name (i);
5730e4b17023SJohn Marino       vr.max = ssa_name (i);
5731e4b17023SJohn Marino     }
5732e4b17023SJohn Marino 
5733e4b17023SJohn Marino   return vr;
5734e4b17023SJohn Marino }
5735e4b17023SJohn Marino 
5736e4b17023SJohn Marino /* Compare all the value ranges for names equivalent to VAR with VAL
5737e4b17023SJohn Marino    using comparison code COMP.  Return the same value returned by
5738e4b17023SJohn Marino    compare_range_with_value, including the setting of
5739e4b17023SJohn Marino    *STRICT_OVERFLOW_P.  */
5740e4b17023SJohn Marino 
5741e4b17023SJohn Marino static tree
compare_name_with_value(enum tree_code comp,tree var,tree val,bool * strict_overflow_p)5742e4b17023SJohn Marino compare_name_with_value (enum tree_code comp, tree var, tree val,
5743e4b17023SJohn Marino 			 bool *strict_overflow_p)
5744e4b17023SJohn Marino {
5745e4b17023SJohn Marino   bitmap_iterator bi;
5746e4b17023SJohn Marino   unsigned i;
5747e4b17023SJohn Marino   bitmap e;
5748e4b17023SJohn Marino   tree retval, t;
5749e4b17023SJohn Marino   int used_strict_overflow;
5750e4b17023SJohn Marino   bool sop;
5751e4b17023SJohn Marino   value_range_t equiv_vr;
5752e4b17023SJohn Marino 
5753e4b17023SJohn Marino   /* Get the set of equivalences for VAR.  */
5754e4b17023SJohn Marino   e = get_value_range (var)->equiv;
5755e4b17023SJohn Marino 
5756e4b17023SJohn Marino   /* Start at -1.  Set it to 0 if we do a comparison without relying
5757e4b17023SJohn Marino      on overflow, or 1 if all comparisons rely on overflow.  */
5758e4b17023SJohn Marino   used_strict_overflow = -1;
5759e4b17023SJohn Marino 
5760e4b17023SJohn Marino   /* Compare vars' value range with val.  */
5761e4b17023SJohn Marino   equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var));
5762e4b17023SJohn Marino   sop = false;
5763e4b17023SJohn Marino   retval = compare_range_with_value (comp, &equiv_vr, val, &sop);
5764e4b17023SJohn Marino   if (retval)
5765e4b17023SJohn Marino     used_strict_overflow = sop ? 1 : 0;
5766e4b17023SJohn Marino 
5767e4b17023SJohn Marino   /* If the equiv set is empty we have done all work we need to do.  */
5768e4b17023SJohn Marino   if (e == NULL)
5769e4b17023SJohn Marino     {
5770e4b17023SJohn Marino       if (retval
5771e4b17023SJohn Marino 	  && used_strict_overflow > 0)
5772e4b17023SJohn Marino 	*strict_overflow_p = true;
5773e4b17023SJohn Marino       return retval;
5774e4b17023SJohn Marino     }
5775e4b17023SJohn Marino 
5776e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
5777e4b17023SJohn Marino     {
5778e4b17023SJohn Marino       equiv_vr = get_vr_for_comparison (i);
5779e4b17023SJohn Marino       sop = false;
5780e4b17023SJohn Marino       t = compare_range_with_value (comp, &equiv_vr, val, &sop);
5781e4b17023SJohn Marino       if (t)
5782e4b17023SJohn Marino 	{
5783e4b17023SJohn Marino 	  /* If we get different answers from different members
5784e4b17023SJohn Marino 	     of the equivalence set this check must be in a dead
5785e4b17023SJohn Marino 	     code region.  Folding it to a trap representation
5786e4b17023SJohn Marino 	     would be correct here.  For now just return don't-know.  */
5787e4b17023SJohn Marino 	  if (retval != NULL
5788e4b17023SJohn Marino 	      && t != retval)
5789e4b17023SJohn Marino 	    {
5790e4b17023SJohn Marino 	      retval = NULL_TREE;
5791e4b17023SJohn Marino 	      break;
5792e4b17023SJohn Marino 	    }
5793e4b17023SJohn Marino 	  retval = t;
5794e4b17023SJohn Marino 
5795e4b17023SJohn Marino 	  if (!sop)
5796e4b17023SJohn Marino 	    used_strict_overflow = 0;
5797e4b17023SJohn Marino 	  else if (used_strict_overflow < 0)
5798e4b17023SJohn Marino 	    used_strict_overflow = 1;
5799e4b17023SJohn Marino 	}
5800e4b17023SJohn Marino     }
5801e4b17023SJohn Marino 
5802e4b17023SJohn Marino   if (retval
5803e4b17023SJohn Marino       && used_strict_overflow > 0)
5804e4b17023SJohn Marino     *strict_overflow_p = true;
5805e4b17023SJohn Marino 
5806e4b17023SJohn Marino   return retval;
5807e4b17023SJohn Marino }
5808e4b17023SJohn Marino 
5809e4b17023SJohn Marino 
5810e4b17023SJohn Marino /* Given a comparison code COMP and names N1 and N2, compare all the
5811e4b17023SJohn Marino    ranges equivalent to N1 against all the ranges equivalent to N2
5812e4b17023SJohn Marino    to determine the value of N1 COMP N2.  Return the same value
5813e4b17023SJohn Marino    returned by compare_ranges.  Set *STRICT_OVERFLOW_P to indicate
5814e4b17023SJohn Marino    whether we relied on an overflow infinity in the comparison.  */
5815e4b17023SJohn Marino 
5816e4b17023SJohn Marino 
5817e4b17023SJohn Marino static tree
compare_names(enum tree_code comp,tree n1,tree n2,bool * strict_overflow_p)5818e4b17023SJohn Marino compare_names (enum tree_code comp, tree n1, tree n2,
5819e4b17023SJohn Marino 	       bool *strict_overflow_p)
5820e4b17023SJohn Marino {
5821e4b17023SJohn Marino   tree t, retval;
5822e4b17023SJohn Marino   bitmap e1, e2;
5823e4b17023SJohn Marino   bitmap_iterator bi1, bi2;
5824e4b17023SJohn Marino   unsigned i1, i2;
5825e4b17023SJohn Marino   int used_strict_overflow;
5826e4b17023SJohn Marino   static bitmap_obstack *s_obstack = NULL;
5827e4b17023SJohn Marino   static bitmap s_e1 = NULL, s_e2 = NULL;
5828e4b17023SJohn Marino 
5829e4b17023SJohn Marino   /* Compare the ranges of every name equivalent to N1 against the
5830e4b17023SJohn Marino      ranges of every name equivalent to N2.  */
5831e4b17023SJohn Marino   e1 = get_value_range (n1)->equiv;
5832e4b17023SJohn Marino   e2 = get_value_range (n2)->equiv;
5833e4b17023SJohn Marino 
5834e4b17023SJohn Marino   /* Use the fake bitmaps if e1 or e2 are not available.  */
5835e4b17023SJohn Marino   if (s_obstack == NULL)
5836e4b17023SJohn Marino     {
5837e4b17023SJohn Marino       s_obstack = XNEW (bitmap_obstack);
5838e4b17023SJohn Marino       bitmap_obstack_initialize (s_obstack);
5839e4b17023SJohn Marino       s_e1 = BITMAP_ALLOC (s_obstack);
5840e4b17023SJohn Marino       s_e2 = BITMAP_ALLOC (s_obstack);
5841e4b17023SJohn Marino     }
5842e4b17023SJohn Marino   if (e1 == NULL)
5843e4b17023SJohn Marino     e1 = s_e1;
5844e4b17023SJohn Marino   if (e2 == NULL)
5845e4b17023SJohn Marino     e2 = s_e2;
5846e4b17023SJohn Marino 
5847e4b17023SJohn Marino   /* Add N1 and N2 to their own set of equivalences to avoid
5848e4b17023SJohn Marino      duplicating the body of the loop just to check N1 and N2
5849e4b17023SJohn Marino      ranges.  */
5850e4b17023SJohn Marino   bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
5851e4b17023SJohn Marino   bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
5852e4b17023SJohn Marino 
5853e4b17023SJohn Marino   /* If the equivalence sets have a common intersection, then the two
5854e4b17023SJohn Marino      names can be compared without checking their ranges.  */
5855e4b17023SJohn Marino   if (bitmap_intersect_p (e1, e2))
5856e4b17023SJohn Marino     {
5857e4b17023SJohn Marino       bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5858e4b17023SJohn Marino       bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5859e4b17023SJohn Marino 
5860e4b17023SJohn Marino       return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
5861e4b17023SJohn Marino 	     ? boolean_true_node
5862e4b17023SJohn Marino 	     : boolean_false_node;
5863e4b17023SJohn Marino     }
5864e4b17023SJohn Marino 
5865e4b17023SJohn Marino   /* Start at -1.  Set it to 0 if we do a comparison without relying
5866e4b17023SJohn Marino      on overflow, or 1 if all comparisons rely on overflow.  */
5867e4b17023SJohn Marino   used_strict_overflow = -1;
5868e4b17023SJohn Marino 
5869e4b17023SJohn Marino   /* Otherwise, compare all the equivalent ranges.  First, add N1 and
5870e4b17023SJohn Marino      N2 to their own set of equivalences to avoid duplicating the body
5871e4b17023SJohn Marino      of the loop just to check N1 and N2 ranges.  */
5872e4b17023SJohn Marino   EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
5873e4b17023SJohn Marino     {
5874e4b17023SJohn Marino       value_range_t vr1 = get_vr_for_comparison (i1);
5875e4b17023SJohn Marino 
5876e4b17023SJohn Marino       t = retval = NULL_TREE;
5877e4b17023SJohn Marino       EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
5878e4b17023SJohn Marino 	{
5879e4b17023SJohn Marino 	  bool sop = false;
5880e4b17023SJohn Marino 
5881e4b17023SJohn Marino 	  value_range_t vr2 = get_vr_for_comparison (i2);
5882e4b17023SJohn Marino 
5883e4b17023SJohn Marino 	  t = compare_ranges (comp, &vr1, &vr2, &sop);
5884e4b17023SJohn Marino 	  if (t)
5885e4b17023SJohn Marino 	    {
5886e4b17023SJohn Marino 	      /* If we get different answers from different members
5887e4b17023SJohn Marino 		 of the equivalence set this check must be in a dead
5888e4b17023SJohn Marino 		 code region.  Folding it to a trap representation
5889e4b17023SJohn Marino 		 would be correct here.  For now just return don't-know.  */
5890e4b17023SJohn Marino 	      if (retval != NULL
5891e4b17023SJohn Marino 		  && t != retval)
5892e4b17023SJohn Marino 		{
5893e4b17023SJohn Marino 		  bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5894e4b17023SJohn Marino 		  bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5895e4b17023SJohn Marino 		  return NULL_TREE;
5896e4b17023SJohn Marino 		}
5897e4b17023SJohn Marino 	      retval = t;
5898e4b17023SJohn Marino 
5899e4b17023SJohn Marino 	      if (!sop)
5900e4b17023SJohn Marino 		used_strict_overflow = 0;
5901e4b17023SJohn Marino 	      else if (used_strict_overflow < 0)
5902e4b17023SJohn Marino 		used_strict_overflow = 1;
5903e4b17023SJohn Marino 	    }
5904e4b17023SJohn Marino 	}
5905e4b17023SJohn Marino 
5906e4b17023SJohn Marino       if (retval)
5907e4b17023SJohn Marino 	{
5908e4b17023SJohn Marino 	  bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5909e4b17023SJohn Marino 	  bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5910e4b17023SJohn Marino 	  if (used_strict_overflow > 0)
5911e4b17023SJohn Marino 	    *strict_overflow_p = true;
5912e4b17023SJohn Marino 	  return retval;
5913e4b17023SJohn Marino 	}
5914e4b17023SJohn Marino     }
5915e4b17023SJohn Marino 
5916e4b17023SJohn Marino   /* None of the equivalent ranges are useful in computing this
5917e4b17023SJohn Marino      comparison.  */
5918e4b17023SJohn Marino   bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5919e4b17023SJohn Marino   bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5920e4b17023SJohn Marino   return NULL_TREE;
5921e4b17023SJohn Marino }
5922e4b17023SJohn Marino 
5923e4b17023SJohn Marino /* Helper function for vrp_evaluate_conditional_warnv.  */
5924e4b17023SJohn Marino 
5925e4b17023SJohn Marino static tree
vrp_evaluate_conditional_warnv_with_ops_using_ranges(enum tree_code code,tree op0,tree op1,bool * strict_overflow_p)5926e4b17023SJohn Marino vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code code,
5927e4b17023SJohn Marino 						      tree op0, tree op1,
5928e4b17023SJohn Marino 						      bool * strict_overflow_p)
5929e4b17023SJohn Marino {
5930e4b17023SJohn Marino   value_range_t *vr0, *vr1;
5931e4b17023SJohn Marino 
5932e4b17023SJohn Marino   vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
5933e4b17023SJohn Marino   vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
5934e4b17023SJohn Marino 
5935e4b17023SJohn Marino   if (vr0 && vr1)
5936e4b17023SJohn Marino     return compare_ranges (code, vr0, vr1, strict_overflow_p);
5937e4b17023SJohn Marino   else if (vr0 && vr1 == NULL)
5938e4b17023SJohn Marino     return compare_range_with_value (code, vr0, op1, strict_overflow_p);
5939e4b17023SJohn Marino   else if (vr0 == NULL && vr1)
5940e4b17023SJohn Marino     return (compare_range_with_value
5941e4b17023SJohn Marino 	    (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
5942e4b17023SJohn Marino   return NULL;
5943e4b17023SJohn Marino }
5944e4b17023SJohn Marino 
5945e4b17023SJohn Marino /* Helper function for vrp_evaluate_conditional_warnv. */
5946e4b17023SJohn Marino 
5947e4b17023SJohn Marino static tree
vrp_evaluate_conditional_warnv_with_ops(enum tree_code code,tree op0,tree op1,bool use_equiv_p,bool * strict_overflow_p,bool * only_ranges)5948e4b17023SJohn Marino vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
5949e4b17023SJohn Marino 					 tree op1, bool use_equiv_p,
5950e4b17023SJohn Marino 					 bool *strict_overflow_p, bool *only_ranges)
5951e4b17023SJohn Marino {
5952e4b17023SJohn Marino   tree ret;
5953e4b17023SJohn Marino   if (only_ranges)
5954e4b17023SJohn Marino     *only_ranges = true;
5955e4b17023SJohn Marino 
5956e4b17023SJohn Marino   /* We only deal with integral and pointer types.  */
5957e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
5958e4b17023SJohn Marino       && !POINTER_TYPE_P (TREE_TYPE (op0)))
5959e4b17023SJohn Marino     return NULL_TREE;
5960e4b17023SJohn Marino 
5961e4b17023SJohn Marino   if (use_equiv_p)
5962e4b17023SJohn Marino     {
5963e4b17023SJohn Marino       if (only_ranges
5964e4b17023SJohn Marino           && (ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
5965e4b17023SJohn Marino 	              (code, op0, op1, strict_overflow_p)))
5966e4b17023SJohn Marino 	return ret;
5967e4b17023SJohn Marino       *only_ranges = false;
5968e4b17023SJohn Marino       if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
5969e4b17023SJohn Marino 	return compare_names (code, op0, op1, strict_overflow_p);
5970e4b17023SJohn Marino       else if (TREE_CODE (op0) == SSA_NAME)
5971e4b17023SJohn Marino 	return compare_name_with_value (code, op0, op1, strict_overflow_p);
5972e4b17023SJohn Marino       else if (TREE_CODE (op1) == SSA_NAME)
5973e4b17023SJohn Marino 	return (compare_name_with_value
5974e4b17023SJohn Marino 		(swap_tree_comparison (code), op1, op0, strict_overflow_p));
5975e4b17023SJohn Marino     }
5976e4b17023SJohn Marino   else
5977e4b17023SJohn Marino     return vrp_evaluate_conditional_warnv_with_ops_using_ranges (code, op0, op1,
5978e4b17023SJohn Marino 								 strict_overflow_p);
5979e4b17023SJohn Marino   return NULL_TREE;
5980e4b17023SJohn Marino }
5981e4b17023SJohn Marino 
5982e4b17023SJohn Marino /* Given (CODE OP0 OP1) within STMT, try to simplify it based on value range
5983e4b17023SJohn Marino    information.  Return NULL if the conditional can not be evaluated.
5984e4b17023SJohn Marino    The ranges of all the names equivalent with the operands in COND
5985e4b17023SJohn Marino    will be used when trying to compute the value.  If the result is
5986e4b17023SJohn Marino    based on undefined signed overflow, issue a warning if
5987e4b17023SJohn Marino    appropriate.  */
5988e4b17023SJohn Marino 
5989e4b17023SJohn Marino static tree
vrp_evaluate_conditional(enum tree_code code,tree op0,tree op1,gimple stmt)5990e4b17023SJohn Marino vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
5991e4b17023SJohn Marino {
5992e4b17023SJohn Marino   bool sop;
5993e4b17023SJohn Marino   tree ret;
5994e4b17023SJohn Marino   bool only_ranges;
5995e4b17023SJohn Marino 
5996e4b17023SJohn Marino   /* Some passes and foldings leak constants with overflow flag set
5997e4b17023SJohn Marino      into the IL.  Avoid doing wrong things with these and bail out.  */
5998e4b17023SJohn Marino   if ((TREE_CODE (op0) == INTEGER_CST
5999e4b17023SJohn Marino        && TREE_OVERFLOW (op0))
6000e4b17023SJohn Marino       || (TREE_CODE (op1) == INTEGER_CST
6001e4b17023SJohn Marino 	  && TREE_OVERFLOW (op1)))
6002e4b17023SJohn Marino     return NULL_TREE;
6003e4b17023SJohn Marino 
6004e4b17023SJohn Marino   sop = false;
6005e4b17023SJohn Marino   ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop,
6006e4b17023SJohn Marino   						 &only_ranges);
6007e4b17023SJohn Marino 
6008e4b17023SJohn Marino   if (ret && sop)
6009e4b17023SJohn Marino     {
6010e4b17023SJohn Marino       enum warn_strict_overflow_code wc;
6011e4b17023SJohn Marino       const char* warnmsg;
6012e4b17023SJohn Marino 
6013e4b17023SJohn Marino       if (is_gimple_min_invariant (ret))
6014e4b17023SJohn Marino 	{
6015e4b17023SJohn Marino 	  wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
6016e4b17023SJohn Marino 	  warnmsg = G_("assuming signed overflow does not occur when "
6017e4b17023SJohn Marino 		       "simplifying conditional to constant");
6018e4b17023SJohn Marino 	}
6019e4b17023SJohn Marino       else
6020e4b17023SJohn Marino 	{
6021e4b17023SJohn Marino 	  wc = WARN_STRICT_OVERFLOW_COMPARISON;
6022e4b17023SJohn Marino 	  warnmsg = G_("assuming signed overflow does not occur when "
6023e4b17023SJohn Marino 		       "simplifying conditional");
6024e4b17023SJohn Marino 	}
6025e4b17023SJohn Marino 
6026e4b17023SJohn Marino       if (issue_strict_overflow_warning (wc))
6027e4b17023SJohn Marino 	{
6028e4b17023SJohn Marino 	  location_t location;
6029e4b17023SJohn Marino 
6030e4b17023SJohn Marino 	  if (!gimple_has_location (stmt))
6031e4b17023SJohn Marino 	    location = input_location;
6032e4b17023SJohn Marino 	  else
6033e4b17023SJohn Marino 	    location = gimple_location (stmt);
6034e4b17023SJohn Marino 	  warning_at (location, OPT_Wstrict_overflow, "%s", warnmsg);
6035e4b17023SJohn Marino 	}
6036e4b17023SJohn Marino     }
6037e4b17023SJohn Marino 
6038e4b17023SJohn Marino   if (warn_type_limits
6039e4b17023SJohn Marino       && ret && only_ranges
6040e4b17023SJohn Marino       && TREE_CODE_CLASS (code) == tcc_comparison
6041e4b17023SJohn Marino       && TREE_CODE (op0) == SSA_NAME)
6042e4b17023SJohn Marino     {
6043e4b17023SJohn Marino       /* If the comparison is being folded and the operand on the LHS
6044e4b17023SJohn Marino 	 is being compared against a constant value that is outside of
6045e4b17023SJohn Marino 	 the natural range of OP0's type, then the predicate will
6046e4b17023SJohn Marino 	 always fold regardless of the value of OP0.  If -Wtype-limits
6047e4b17023SJohn Marino 	 was specified, emit a warning.  */
6048e4b17023SJohn Marino       tree type = TREE_TYPE (op0);
6049e4b17023SJohn Marino       value_range_t *vr0 = get_value_range (op0);
6050e4b17023SJohn Marino 
6051e4b17023SJohn Marino       if (vr0->type != VR_VARYING
6052e4b17023SJohn Marino 	  && INTEGRAL_TYPE_P (type)
6053e4b17023SJohn Marino 	  && vrp_val_is_min (vr0->min)
6054e4b17023SJohn Marino 	  && vrp_val_is_max (vr0->max)
6055e4b17023SJohn Marino 	  && is_gimple_min_invariant (op1))
6056e4b17023SJohn Marino 	{
6057e4b17023SJohn Marino 	  location_t location;
6058e4b17023SJohn Marino 
6059e4b17023SJohn Marino 	  if (!gimple_has_location (stmt))
6060e4b17023SJohn Marino 	    location = input_location;
6061e4b17023SJohn Marino 	  else
6062e4b17023SJohn Marino 	    location = gimple_location (stmt);
6063e4b17023SJohn Marino 
6064e4b17023SJohn Marino 	  warning_at (location, OPT_Wtype_limits,
6065e4b17023SJohn Marino 		      integer_zerop (ret)
6066e4b17023SJohn Marino 		      ? G_("comparison always false "
6067e4b17023SJohn Marino                            "due to limited range of data type")
6068e4b17023SJohn Marino 		      : G_("comparison always true "
6069e4b17023SJohn Marino                            "due to limited range of data type"));
6070e4b17023SJohn Marino 	}
6071e4b17023SJohn Marino     }
6072e4b17023SJohn Marino 
6073e4b17023SJohn Marino   return ret;
6074e4b17023SJohn Marino }
6075e4b17023SJohn Marino 
6076e4b17023SJohn Marino 
6077e4b17023SJohn Marino /* Visit conditional statement STMT.  If we can determine which edge
6078e4b17023SJohn Marino    will be taken out of STMT's basic block, record it in
6079e4b17023SJohn Marino    *TAKEN_EDGE_P and return SSA_PROP_INTERESTING.  Otherwise, return
6080e4b17023SJohn Marino    SSA_PROP_VARYING.  */
6081e4b17023SJohn Marino 
6082e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_cond_stmt(gimple stmt,edge * taken_edge_p)6083e4b17023SJohn Marino vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
6084e4b17023SJohn Marino {
6085e4b17023SJohn Marino   tree val;
6086e4b17023SJohn Marino   bool sop;
6087e4b17023SJohn Marino 
6088e4b17023SJohn Marino   *taken_edge_p = NULL;
6089e4b17023SJohn Marino 
6090e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6091e4b17023SJohn Marino     {
6092e4b17023SJohn Marino       tree use;
6093e4b17023SJohn Marino       ssa_op_iter i;
6094e4b17023SJohn Marino 
6095e4b17023SJohn Marino       fprintf (dump_file, "\nVisiting conditional with predicate: ");
6096e4b17023SJohn Marino       print_gimple_stmt (dump_file, stmt, 0, 0);
6097e4b17023SJohn Marino       fprintf (dump_file, "\nWith known ranges\n");
6098e4b17023SJohn Marino 
6099e4b17023SJohn Marino       FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
6100e4b17023SJohn Marino 	{
6101e4b17023SJohn Marino 	  fprintf (dump_file, "\t");
6102e4b17023SJohn Marino 	  print_generic_expr (dump_file, use, 0);
6103e4b17023SJohn Marino 	  fprintf (dump_file, ": ");
6104e4b17023SJohn Marino 	  dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
6105e4b17023SJohn Marino 	}
6106e4b17023SJohn Marino 
6107e4b17023SJohn Marino       fprintf (dump_file, "\n");
6108e4b17023SJohn Marino     }
6109e4b17023SJohn Marino 
6110e4b17023SJohn Marino   /* Compute the value of the predicate COND by checking the known
6111e4b17023SJohn Marino      ranges of each of its operands.
6112e4b17023SJohn Marino 
6113e4b17023SJohn Marino      Note that we cannot evaluate all the equivalent ranges here
6114e4b17023SJohn Marino      because those ranges may not yet be final and with the current
6115e4b17023SJohn Marino      propagation strategy, we cannot determine when the value ranges
6116e4b17023SJohn Marino      of the names in the equivalence set have changed.
6117e4b17023SJohn Marino 
6118e4b17023SJohn Marino      For instance, given the following code fragment
6119e4b17023SJohn Marino 
6120e4b17023SJohn Marino         i_5 = PHI <8, i_13>
6121e4b17023SJohn Marino 	...
6122e4b17023SJohn Marino      	i_14 = ASSERT_EXPR <i_5, i_5 != 0>
6123e4b17023SJohn Marino 	if (i_14 == 1)
6124e4b17023SJohn Marino 	  ...
6125e4b17023SJohn Marino 
6126e4b17023SJohn Marino      Assume that on the first visit to i_14, i_5 has the temporary
6127e4b17023SJohn Marino      range [8, 8] because the second argument to the PHI function is
6128e4b17023SJohn Marino      not yet executable.  We derive the range ~[0, 0] for i_14 and the
6129e4b17023SJohn Marino      equivalence set { i_5 }.  So, when we visit 'if (i_14 == 1)' for
6130e4b17023SJohn Marino      the first time, since i_14 is equivalent to the range [8, 8], we
6131e4b17023SJohn Marino      determine that the predicate is always false.
6132e4b17023SJohn Marino 
6133e4b17023SJohn Marino      On the next round of propagation, i_13 is determined to be
6134e4b17023SJohn Marino      VARYING, which causes i_5 to drop down to VARYING.  So, another
6135e4b17023SJohn Marino      visit to i_14 is scheduled.  In this second visit, we compute the
6136e4b17023SJohn Marino      exact same range and equivalence set for i_14, namely ~[0, 0] and
6137e4b17023SJohn Marino      { i_5 }.  But we did not have the previous range for i_5
6138e4b17023SJohn Marino      registered, so vrp_visit_assignment thinks that the range for
6139e4b17023SJohn Marino      i_14 has not changed.  Therefore, the predicate 'if (i_14 == 1)'
6140e4b17023SJohn Marino      is not visited again, which stops propagation from visiting
6141e4b17023SJohn Marino      statements in the THEN clause of that if().
6142e4b17023SJohn Marino 
6143e4b17023SJohn Marino      To properly fix this we would need to keep the previous range
6144e4b17023SJohn Marino      value for the names in the equivalence set.  This way we would've
6145e4b17023SJohn Marino      discovered that from one visit to the other i_5 changed from
6146e4b17023SJohn Marino      range [8, 8] to VR_VARYING.
6147e4b17023SJohn Marino 
6148e4b17023SJohn Marino      However, fixing this apparent limitation may not be worth the
6149e4b17023SJohn Marino      additional checking.  Testing on several code bases (GCC, DLV,
6150e4b17023SJohn Marino      MICO, TRAMP3D and SPEC2000) showed that doing this results in
6151e4b17023SJohn Marino      4 more predicates folded in SPEC.  */
6152e4b17023SJohn Marino   sop = false;
6153e4b17023SJohn Marino 
6154e4b17023SJohn Marino   val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
6155e4b17023SJohn Marino 						 gimple_cond_lhs (stmt),
6156e4b17023SJohn Marino 						 gimple_cond_rhs (stmt),
6157e4b17023SJohn Marino 						 false, &sop, NULL);
6158e4b17023SJohn Marino   if (val)
6159e4b17023SJohn Marino     {
6160e4b17023SJohn Marino       if (!sop)
6161e4b17023SJohn Marino 	*taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
6162e4b17023SJohn Marino       else
6163e4b17023SJohn Marino 	{
6164e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
6165e4b17023SJohn Marino 	    fprintf (dump_file,
6166e4b17023SJohn Marino 		     "\nIgnoring predicate evaluation because "
6167e4b17023SJohn Marino 		     "it assumes that signed overflow is undefined");
6168e4b17023SJohn Marino 	  val = NULL_TREE;
6169e4b17023SJohn Marino 	}
6170e4b17023SJohn Marino     }
6171e4b17023SJohn Marino 
6172e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6173e4b17023SJohn Marino     {
6174e4b17023SJohn Marino       fprintf (dump_file, "\nPredicate evaluates to: ");
6175e4b17023SJohn Marino       if (val == NULL_TREE)
6176e4b17023SJohn Marino 	fprintf (dump_file, "DON'T KNOW\n");
6177e4b17023SJohn Marino       else
6178e4b17023SJohn Marino 	print_generic_stmt (dump_file, val, 0);
6179e4b17023SJohn Marino     }
6180e4b17023SJohn Marino 
6181e4b17023SJohn Marino   return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
6182e4b17023SJohn Marino }
6183e4b17023SJohn Marino 
6184e4b17023SJohn Marino /* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
6185e4b17023SJohn Marino    that includes the value VAL.  The search is restricted to the range
6186e4b17023SJohn Marino    [START_IDX, n - 1] where n is the size of VEC.
6187e4b17023SJohn Marino 
6188e4b17023SJohn Marino    If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
6189e4b17023SJohn Marino    returned.
6190e4b17023SJohn Marino 
6191e4b17023SJohn Marino    If there is no CASE_LABEL for VAL and there is one that is larger than VAL,
6192e4b17023SJohn Marino    it is placed in IDX and false is returned.
6193e4b17023SJohn Marino 
6194e4b17023SJohn Marino    If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
6195e4b17023SJohn Marino    returned. */
6196e4b17023SJohn Marino 
6197e4b17023SJohn Marino static bool
find_case_label_index(gimple stmt,size_t start_idx,tree val,size_t * idx)6198e4b17023SJohn Marino find_case_label_index (gimple stmt, size_t start_idx, tree val, size_t *idx)
6199e4b17023SJohn Marino {
6200e4b17023SJohn Marino   size_t n = gimple_switch_num_labels (stmt);
6201e4b17023SJohn Marino   size_t low, high;
6202e4b17023SJohn Marino 
6203e4b17023SJohn Marino   /* Find case label for minimum of the value range or the next one.
6204e4b17023SJohn Marino      At each iteration we are searching in [low, high - 1]. */
6205e4b17023SJohn Marino 
6206e4b17023SJohn Marino   for (low = start_idx, high = n; high != low; )
6207e4b17023SJohn Marino     {
6208e4b17023SJohn Marino       tree t;
6209e4b17023SJohn Marino       int cmp;
6210e4b17023SJohn Marino       /* Note that i != high, so we never ask for n. */
6211e4b17023SJohn Marino       size_t i = (high + low) / 2;
6212e4b17023SJohn Marino       t = gimple_switch_label (stmt, i);
6213e4b17023SJohn Marino 
6214e4b17023SJohn Marino       /* Cache the result of comparing CASE_LOW and val.  */
6215e4b17023SJohn Marino       cmp = tree_int_cst_compare (CASE_LOW (t), val);
6216e4b17023SJohn Marino 
6217e4b17023SJohn Marino       if (cmp == 0)
6218e4b17023SJohn Marino 	{
6219e4b17023SJohn Marino 	  /* Ranges cannot be empty. */
6220e4b17023SJohn Marino 	  *idx = i;
6221e4b17023SJohn Marino 	  return true;
6222e4b17023SJohn Marino 	}
6223e4b17023SJohn Marino       else if (cmp > 0)
6224e4b17023SJohn Marino         high = i;
6225e4b17023SJohn Marino       else
6226e4b17023SJohn Marino 	{
6227e4b17023SJohn Marino 	  low = i + 1;
6228e4b17023SJohn Marino 	  if (CASE_HIGH (t) != NULL
6229e4b17023SJohn Marino 	      && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
6230e4b17023SJohn Marino 	    {
6231e4b17023SJohn Marino 	      *idx = i;
6232e4b17023SJohn Marino 	      return true;
6233e4b17023SJohn Marino 	    }
6234e4b17023SJohn Marino         }
6235e4b17023SJohn Marino     }
6236e4b17023SJohn Marino 
6237e4b17023SJohn Marino   *idx = high;
6238e4b17023SJohn Marino   return false;
6239e4b17023SJohn Marino }
6240e4b17023SJohn Marino 
6241e4b17023SJohn Marino /* Searches the case label vector VEC for the range of CASE_LABELs that is used
6242e4b17023SJohn Marino    for values between MIN and MAX. The first index is placed in MIN_IDX. The
6243e4b17023SJohn Marino    last index is placed in MAX_IDX. If the range of CASE_LABELs is empty
6244e4b17023SJohn Marino    then MAX_IDX < MIN_IDX.
6245e4b17023SJohn Marino    Returns true if the default label is not needed. */
6246e4b17023SJohn Marino 
6247e4b17023SJohn Marino static bool
find_case_label_range(gimple stmt,tree min,tree max,size_t * min_idx,size_t * max_idx)6248e4b17023SJohn Marino find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx,
6249e4b17023SJohn Marino 		       size_t *max_idx)
6250e4b17023SJohn Marino {
6251e4b17023SJohn Marino   size_t i, j;
6252e4b17023SJohn Marino   bool min_take_default = !find_case_label_index (stmt, 1, min, &i);
6253e4b17023SJohn Marino   bool max_take_default = !find_case_label_index (stmt, i, max, &j);
6254e4b17023SJohn Marino 
6255e4b17023SJohn Marino   if (i == j
6256e4b17023SJohn Marino       && min_take_default
6257e4b17023SJohn Marino       && max_take_default)
6258e4b17023SJohn Marino     {
6259e4b17023SJohn Marino       /* Only the default case label reached.
6260e4b17023SJohn Marino          Return an empty range. */
6261e4b17023SJohn Marino       *min_idx = 1;
6262e4b17023SJohn Marino       *max_idx = 0;
6263e4b17023SJohn Marino       return false;
6264e4b17023SJohn Marino     }
6265e4b17023SJohn Marino   else
6266e4b17023SJohn Marino     {
6267e4b17023SJohn Marino       bool take_default = min_take_default || max_take_default;
6268e4b17023SJohn Marino       tree low, high;
6269e4b17023SJohn Marino       size_t k;
6270e4b17023SJohn Marino 
6271e4b17023SJohn Marino       if (max_take_default)
6272e4b17023SJohn Marino 	j--;
6273e4b17023SJohn Marino 
6274e4b17023SJohn Marino       /* If the case label range is continuous, we do not need
6275e4b17023SJohn Marino 	 the default case label.  Verify that.  */
6276e4b17023SJohn Marino       high = CASE_LOW (gimple_switch_label (stmt, i));
6277e4b17023SJohn Marino       if (CASE_HIGH (gimple_switch_label (stmt, i)))
6278e4b17023SJohn Marino 	high = CASE_HIGH (gimple_switch_label (stmt, i));
6279e4b17023SJohn Marino       for (k = i + 1; k <= j; ++k)
6280e4b17023SJohn Marino 	{
6281e4b17023SJohn Marino 	  low = CASE_LOW (gimple_switch_label (stmt, k));
6282e4b17023SJohn Marino 	  if (!integer_onep (int_const_binop (MINUS_EXPR, low, high)))
6283e4b17023SJohn Marino 	    {
6284e4b17023SJohn Marino 	      take_default = true;
6285e4b17023SJohn Marino 	      break;
6286e4b17023SJohn Marino 	    }
6287e4b17023SJohn Marino 	  high = low;
6288e4b17023SJohn Marino 	  if (CASE_HIGH (gimple_switch_label (stmt, k)))
6289e4b17023SJohn Marino 	    high = CASE_HIGH (gimple_switch_label (stmt, k));
6290e4b17023SJohn Marino 	}
6291e4b17023SJohn Marino 
6292e4b17023SJohn Marino       *min_idx = i;
6293e4b17023SJohn Marino       *max_idx = j;
6294e4b17023SJohn Marino       return !take_default;
6295e4b17023SJohn Marino     }
6296e4b17023SJohn Marino }
6297e4b17023SJohn Marino 
6298e4b17023SJohn Marino /* Visit switch statement STMT.  If we can determine which edge
6299e4b17023SJohn Marino    will be taken out of STMT's basic block, record it in
6300e4b17023SJohn Marino    *TAKEN_EDGE_P and return SSA_PROP_INTERESTING.  Otherwise, return
6301e4b17023SJohn Marino    SSA_PROP_VARYING.  */
6302e4b17023SJohn Marino 
6303e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_switch_stmt(gimple stmt,edge * taken_edge_p)6304e4b17023SJohn Marino vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p)
6305e4b17023SJohn Marino {
6306e4b17023SJohn Marino   tree op, val;
6307e4b17023SJohn Marino   value_range_t *vr;
6308e4b17023SJohn Marino   size_t i = 0, j = 0;
6309e4b17023SJohn Marino   bool take_default;
6310e4b17023SJohn Marino 
6311e4b17023SJohn Marino   *taken_edge_p = NULL;
6312e4b17023SJohn Marino   op = gimple_switch_index (stmt);
6313e4b17023SJohn Marino   if (TREE_CODE (op) != SSA_NAME)
6314e4b17023SJohn Marino     return SSA_PROP_VARYING;
6315e4b17023SJohn Marino 
6316e4b17023SJohn Marino   vr = get_value_range (op);
6317e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6318e4b17023SJohn Marino     {
6319e4b17023SJohn Marino       fprintf (dump_file, "\nVisiting switch expression with operand ");
6320e4b17023SJohn Marino       print_generic_expr (dump_file, op, 0);
6321e4b17023SJohn Marino       fprintf (dump_file, " with known range ");
6322e4b17023SJohn Marino       dump_value_range (dump_file, vr);
6323e4b17023SJohn Marino       fprintf (dump_file, "\n");
6324e4b17023SJohn Marino     }
6325e4b17023SJohn Marino 
6326e4b17023SJohn Marino   if (vr->type != VR_RANGE
6327e4b17023SJohn Marino       || symbolic_range_p (vr))
6328e4b17023SJohn Marino     return SSA_PROP_VARYING;
6329e4b17023SJohn Marino 
6330e4b17023SJohn Marino   /* Find the single edge that is taken from the switch expression.  */
6331e4b17023SJohn Marino   take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
6332e4b17023SJohn Marino 
6333e4b17023SJohn Marino   /* Check if the range spans no CASE_LABEL. If so, we only reach the default
6334e4b17023SJohn Marino      label */
6335e4b17023SJohn Marino   if (j < i)
6336e4b17023SJohn Marino     {
6337e4b17023SJohn Marino       gcc_assert (take_default);
6338e4b17023SJohn Marino       val = gimple_switch_default_label (stmt);
6339e4b17023SJohn Marino     }
6340e4b17023SJohn Marino   else
6341e4b17023SJohn Marino     {
6342e4b17023SJohn Marino       /* Check if labels with index i to j and maybe the default label
6343e4b17023SJohn Marino 	 are all reaching the same label.  */
6344e4b17023SJohn Marino 
6345e4b17023SJohn Marino       val = gimple_switch_label (stmt, i);
6346e4b17023SJohn Marino       if (take_default
6347e4b17023SJohn Marino 	  && CASE_LABEL (gimple_switch_default_label (stmt))
6348e4b17023SJohn Marino 	  != CASE_LABEL (val))
6349e4b17023SJohn Marino 	{
6350e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
6351e4b17023SJohn Marino 	    fprintf (dump_file, "  not a single destination for this "
6352e4b17023SJohn Marino 		     "range\n");
6353e4b17023SJohn Marino           return SSA_PROP_VARYING;
6354e4b17023SJohn Marino 	}
6355e4b17023SJohn Marino       for (++i; i <= j; ++i)
6356e4b17023SJohn Marino         {
6357e4b17023SJohn Marino           if (CASE_LABEL (gimple_switch_label (stmt, i)) != CASE_LABEL (val))
6358e4b17023SJohn Marino 	    {
6359e4b17023SJohn Marino 	      if (dump_file && (dump_flags & TDF_DETAILS))
6360e4b17023SJohn Marino 		fprintf (dump_file, "  not a single destination for this "
6361e4b17023SJohn Marino 			 "range\n");
6362e4b17023SJohn Marino 	      return SSA_PROP_VARYING;
6363e4b17023SJohn Marino 	    }
6364e4b17023SJohn Marino         }
6365e4b17023SJohn Marino     }
6366e4b17023SJohn Marino 
6367e4b17023SJohn Marino   *taken_edge_p = find_edge (gimple_bb (stmt),
6368e4b17023SJohn Marino 			     label_to_block (CASE_LABEL (val)));
6369e4b17023SJohn Marino 
6370e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6371e4b17023SJohn Marino     {
6372e4b17023SJohn Marino       fprintf (dump_file, "  will take edge to ");
6373e4b17023SJohn Marino       print_generic_stmt (dump_file, CASE_LABEL (val), 0);
6374e4b17023SJohn Marino     }
6375e4b17023SJohn Marino 
6376e4b17023SJohn Marino   return SSA_PROP_INTERESTING;
6377e4b17023SJohn Marino }
6378e4b17023SJohn Marino 
6379e4b17023SJohn Marino 
6380e4b17023SJohn Marino /* Evaluate statement STMT.  If the statement produces a useful range,
6381e4b17023SJohn Marino    return SSA_PROP_INTERESTING and record the SSA name with the
6382e4b17023SJohn Marino    interesting range into *OUTPUT_P.
6383e4b17023SJohn Marino 
6384e4b17023SJohn Marino    If STMT is a conditional branch and we can determine its truth
6385e4b17023SJohn Marino    value, the taken edge is recorded in *TAKEN_EDGE_P.
6386e4b17023SJohn Marino 
6387e4b17023SJohn Marino    If STMT produces a varying value, return SSA_PROP_VARYING.  */
6388e4b17023SJohn Marino 
6389e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_stmt(gimple stmt,edge * taken_edge_p,tree * output_p)6390e4b17023SJohn Marino vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
6391e4b17023SJohn Marino {
6392e4b17023SJohn Marino   tree def;
6393e4b17023SJohn Marino   ssa_op_iter iter;
6394e4b17023SJohn Marino 
6395e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6396e4b17023SJohn Marino     {
6397e4b17023SJohn Marino       fprintf (dump_file, "\nVisiting statement:\n");
6398e4b17023SJohn Marino       print_gimple_stmt (dump_file, stmt, 0, dump_flags);
6399e4b17023SJohn Marino       fprintf (dump_file, "\n");
6400e4b17023SJohn Marino     }
6401e4b17023SJohn Marino 
6402e4b17023SJohn Marino   if (!stmt_interesting_for_vrp (stmt))
6403e4b17023SJohn Marino     gcc_assert (stmt_ends_bb_p (stmt));
6404e4b17023SJohn Marino   else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
6405e4b17023SJohn Marino     {
6406e4b17023SJohn Marino       /* In general, assignments with virtual operands are not useful
6407e4b17023SJohn Marino 	 for deriving ranges, with the obvious exception of calls to
6408e4b17023SJohn Marino 	 builtin functions.  */
6409e4b17023SJohn Marino       if ((is_gimple_call (stmt)
6410e4b17023SJohn Marino 	   && gimple_call_fndecl (stmt) != NULL_TREE
6411e4b17023SJohn Marino 	   && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
6412e4b17023SJohn Marino 	  || !gimple_vuse (stmt))
6413e4b17023SJohn Marino 	return vrp_visit_assignment_or_call (stmt, output_p);
6414e4b17023SJohn Marino     }
6415e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_COND)
6416e4b17023SJohn Marino     return vrp_visit_cond_stmt (stmt, taken_edge_p);
6417e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_SWITCH)
6418e4b17023SJohn Marino     return vrp_visit_switch_stmt (stmt, taken_edge_p);
6419e4b17023SJohn Marino 
6420e4b17023SJohn Marino   /* All other statements produce nothing of interest for VRP, so mark
6421e4b17023SJohn Marino      their outputs varying and prevent further simulation.  */
6422e4b17023SJohn Marino   FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
6423e4b17023SJohn Marino     set_value_range_to_varying (get_value_range (def));
6424e4b17023SJohn Marino 
6425e4b17023SJohn Marino   return SSA_PROP_VARYING;
6426e4b17023SJohn Marino }
6427e4b17023SJohn Marino 
6428e4b17023SJohn Marino 
6429e4b17023SJohn Marino /* Meet operation for value ranges.  Given two value ranges VR0 and
6430e4b17023SJohn Marino    VR1, store in VR0 a range that contains both VR0 and VR1.  This
6431e4b17023SJohn Marino    may not be the smallest possible such range.  */
6432e4b17023SJohn Marino 
6433e4b17023SJohn Marino static void
vrp_meet(value_range_t * vr0,value_range_t * vr1)6434e4b17023SJohn Marino vrp_meet (value_range_t *vr0, value_range_t *vr1)
6435e4b17023SJohn Marino {
6436e4b17023SJohn Marino   if (vr0->type == VR_UNDEFINED)
6437e4b17023SJohn Marino     {
6438e4b17023SJohn Marino       /* Drop equivalences.  See PR53465.  */
6439e4b17023SJohn Marino       set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL);
6440e4b17023SJohn Marino       return;
6441e4b17023SJohn Marino     }
6442e4b17023SJohn Marino 
6443e4b17023SJohn Marino   if (vr1->type == VR_UNDEFINED)
6444e4b17023SJohn Marino     {
6445e4b17023SJohn Marino       /* VR0 already has the resulting range, just drop equivalences.
6446e4b17023SJohn Marino 	 See PR53465.  */
6447e4b17023SJohn Marino       if (vr0->equiv)
6448e4b17023SJohn Marino 	bitmap_clear (vr0->equiv);
6449e4b17023SJohn Marino       return;
6450e4b17023SJohn Marino     }
6451e4b17023SJohn Marino 
6452e4b17023SJohn Marino   if (vr0->type == VR_VARYING)
6453e4b17023SJohn Marino     {
6454e4b17023SJohn Marino       /* Nothing to do.  VR0 already has the resulting range.  */
6455e4b17023SJohn Marino       return;
6456e4b17023SJohn Marino     }
6457e4b17023SJohn Marino 
6458e4b17023SJohn Marino   if (vr1->type == VR_VARYING)
6459e4b17023SJohn Marino     {
6460e4b17023SJohn Marino       set_value_range_to_varying (vr0);
6461e4b17023SJohn Marino       return;
6462e4b17023SJohn Marino     }
6463e4b17023SJohn Marino 
6464e4b17023SJohn Marino   if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
6465e4b17023SJohn Marino     {
6466e4b17023SJohn Marino       int cmp;
6467e4b17023SJohn Marino       tree min, max;
6468e4b17023SJohn Marino 
6469e4b17023SJohn Marino       /* Compute the convex hull of the ranges.  The lower limit of
6470e4b17023SJohn Marino          the new range is the minimum of the two ranges.  If they
6471e4b17023SJohn Marino 	 cannot be compared, then give up.  */
6472e4b17023SJohn Marino       cmp = compare_values (vr0->min, vr1->min);
6473e4b17023SJohn Marino       if (cmp == 0 || cmp == 1)
6474e4b17023SJohn Marino         min = vr1->min;
6475e4b17023SJohn Marino       else if (cmp == -1)
6476e4b17023SJohn Marino         min = vr0->min;
6477e4b17023SJohn Marino       else
6478e4b17023SJohn Marino 	goto give_up;
6479e4b17023SJohn Marino 
6480e4b17023SJohn Marino       /* Similarly, the upper limit of the new range is the maximum
6481e4b17023SJohn Marino          of the two ranges.  If they cannot be compared, then
6482e4b17023SJohn Marino 	 give up.  */
6483e4b17023SJohn Marino       cmp = compare_values (vr0->max, vr1->max);
6484e4b17023SJohn Marino       if (cmp == 0 || cmp == -1)
6485e4b17023SJohn Marino         max = vr1->max;
6486e4b17023SJohn Marino       else if (cmp == 1)
6487e4b17023SJohn Marino         max = vr0->max;
6488e4b17023SJohn Marino       else
6489e4b17023SJohn Marino 	goto give_up;
6490e4b17023SJohn Marino 
6491e4b17023SJohn Marino       /* Check for useless ranges.  */
6492e4b17023SJohn Marino       if (INTEGRAL_TYPE_P (TREE_TYPE (min))
6493e4b17023SJohn Marino 	  && ((vrp_val_is_min (min) || is_overflow_infinity (min))
6494e4b17023SJohn Marino 	      && (vrp_val_is_max (max) || is_overflow_infinity (max))))
6495e4b17023SJohn Marino 	goto give_up;
6496e4b17023SJohn Marino 
6497e4b17023SJohn Marino       /* The resulting set of equivalences is the intersection of
6498e4b17023SJohn Marino 	 the two sets.  */
6499e4b17023SJohn Marino       if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6500e4b17023SJohn Marino         bitmap_and_into (vr0->equiv, vr1->equiv);
6501e4b17023SJohn Marino       else if (vr0->equiv && !vr1->equiv)
6502e4b17023SJohn Marino         bitmap_clear (vr0->equiv);
6503e4b17023SJohn Marino 
6504e4b17023SJohn Marino       set_value_range (vr0, vr0->type, min, max, vr0->equiv);
6505e4b17023SJohn Marino     }
6506e4b17023SJohn Marino   else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
6507e4b17023SJohn Marino     {
6508e4b17023SJohn Marino       /* Two anti-ranges meet only if their complements intersect.
6509e4b17023SJohn Marino          Only handle the case of identical ranges.  */
6510e4b17023SJohn Marino       if (compare_values (vr0->min, vr1->min) == 0
6511e4b17023SJohn Marino 	  && compare_values (vr0->max, vr1->max) == 0
6512e4b17023SJohn Marino 	  && compare_values (vr0->min, vr0->max) == 0)
6513e4b17023SJohn Marino 	{
6514e4b17023SJohn Marino 	  /* The resulting set of equivalences is the intersection of
6515e4b17023SJohn Marino 	     the two sets.  */
6516e4b17023SJohn Marino 	  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6517e4b17023SJohn Marino 	    bitmap_and_into (vr0->equiv, vr1->equiv);
6518e4b17023SJohn Marino 	  else if (vr0->equiv && !vr1->equiv)
6519e4b17023SJohn Marino 	    bitmap_clear (vr0->equiv);
6520e4b17023SJohn Marino 	}
6521e4b17023SJohn Marino       else
6522e4b17023SJohn Marino 	goto give_up;
6523e4b17023SJohn Marino     }
6524e4b17023SJohn Marino   else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
6525e4b17023SJohn Marino     {
6526e4b17023SJohn Marino       /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
6527e4b17023SJohn Marino          only handle the case where the ranges have an empty intersection.
6528e4b17023SJohn Marino 	 The result of the meet operation is the anti-range.  */
6529e4b17023SJohn Marino       if (!symbolic_range_p (vr0)
6530e4b17023SJohn Marino 	  && !symbolic_range_p (vr1)
6531e4b17023SJohn Marino 	  && !value_ranges_intersect_p (vr0, vr1))
6532e4b17023SJohn Marino 	{
6533e4b17023SJohn Marino 	  /* Copy most of VR1 into VR0.  Don't copy VR1's equivalence
6534e4b17023SJohn Marino 	     set.  We need to compute the intersection of the two
6535e4b17023SJohn Marino 	     equivalence sets.  */
6536e4b17023SJohn Marino 	  if (vr1->type == VR_ANTI_RANGE)
6537e4b17023SJohn Marino 	    set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);
6538e4b17023SJohn Marino 
6539e4b17023SJohn Marino 	  /* The resulting set of equivalences is the intersection of
6540e4b17023SJohn Marino 	     the two sets.  */
6541e4b17023SJohn Marino 	  if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6542e4b17023SJohn Marino 	    bitmap_and_into (vr0->equiv, vr1->equiv);
6543e4b17023SJohn Marino 	  else if (vr0->equiv && !vr1->equiv)
6544e4b17023SJohn Marino 	    bitmap_clear (vr0->equiv);
6545e4b17023SJohn Marino 	}
6546e4b17023SJohn Marino       else
6547e4b17023SJohn Marino 	goto give_up;
6548e4b17023SJohn Marino     }
6549e4b17023SJohn Marino   else
6550e4b17023SJohn Marino     gcc_unreachable ();
6551e4b17023SJohn Marino 
6552e4b17023SJohn Marino   return;
6553e4b17023SJohn Marino 
6554e4b17023SJohn Marino give_up:
6555e4b17023SJohn Marino   /* Failed to find an efficient meet.  Before giving up and setting
6556e4b17023SJohn Marino      the result to VARYING, see if we can at least derive a useful
6557e4b17023SJohn Marino      anti-range.  FIXME, all this nonsense about distinguishing
6558e4b17023SJohn Marino      anti-ranges from ranges is necessary because of the odd
6559e4b17023SJohn Marino      semantics of range_includes_zero_p and friends.  */
6560e4b17023SJohn Marino   if (!symbolic_range_p (vr0)
6561e4b17023SJohn Marino       && ((vr0->type == VR_RANGE
6562e4b17023SJohn Marino 	   && range_includes_zero_p (vr0->min, vr0->max) == 0)
6563e4b17023SJohn Marino 	  || (vr0->type == VR_ANTI_RANGE
6564e4b17023SJohn Marino 	      && range_includes_zero_p (vr0->min, vr0->max) == 1))
6565e4b17023SJohn Marino       && !symbolic_range_p (vr1)
6566e4b17023SJohn Marino       && ((vr1->type == VR_RANGE
6567e4b17023SJohn Marino 	   && range_includes_zero_p (vr1->min, vr1->max) == 0)
6568e4b17023SJohn Marino 	  || (vr1->type == VR_ANTI_RANGE
6569e4b17023SJohn Marino 	      && range_includes_zero_p (vr1->min, vr1->max) == 1)))
6570e4b17023SJohn Marino     {
6571e4b17023SJohn Marino       set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
6572e4b17023SJohn Marino 
6573e4b17023SJohn Marino       /* Since this meet operation did not result from the meeting of
6574e4b17023SJohn Marino 	 two equivalent names, VR0 cannot have any equivalences.  */
6575e4b17023SJohn Marino       if (vr0->equiv)
6576e4b17023SJohn Marino 	bitmap_clear (vr0->equiv);
6577e4b17023SJohn Marino     }
6578e4b17023SJohn Marino   else
6579e4b17023SJohn Marino     set_value_range_to_varying (vr0);
6580e4b17023SJohn Marino }
6581e4b17023SJohn Marino 
6582e4b17023SJohn Marino 
6583e4b17023SJohn Marino /* Visit all arguments for PHI node PHI that flow through executable
6584e4b17023SJohn Marino    edges.  If a valid value range can be derived from all the incoming
6585e4b17023SJohn Marino    value ranges, set a new range for the LHS of PHI.  */
6586e4b17023SJohn Marino 
6587e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_phi_node(gimple phi)6588e4b17023SJohn Marino vrp_visit_phi_node (gimple phi)
6589e4b17023SJohn Marino {
6590e4b17023SJohn Marino   size_t i;
6591e4b17023SJohn Marino   tree lhs = PHI_RESULT (phi);
6592e4b17023SJohn Marino   value_range_t *lhs_vr = get_value_range (lhs);
6593e4b17023SJohn Marino   value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6594e4b17023SJohn Marino   bool first = true;
6595e4b17023SJohn Marino   int edges, old_edges;
6596e4b17023SJohn Marino   struct loop *l;
6597e4b17023SJohn Marino 
6598e4b17023SJohn Marino   if (dump_file && (dump_flags & TDF_DETAILS))
6599e4b17023SJohn Marino     {
6600e4b17023SJohn Marino       fprintf (dump_file, "\nVisiting PHI node: ");
6601e4b17023SJohn Marino       print_gimple_stmt (dump_file, phi, 0, dump_flags);
6602e4b17023SJohn Marino     }
6603e4b17023SJohn Marino 
6604e4b17023SJohn Marino   edges = 0;
6605e4b17023SJohn Marino   for (i = 0; i < gimple_phi_num_args (phi); i++)
6606e4b17023SJohn Marino     {
6607e4b17023SJohn Marino       edge e = gimple_phi_arg_edge (phi, i);
6608e4b17023SJohn Marino 
6609e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
6610e4b17023SJohn Marino 	{
6611e4b17023SJohn Marino 	  fprintf (dump_file,
6612e4b17023SJohn Marino 	      "\n    Argument #%d (%d -> %d %sexecutable)\n",
6613e4b17023SJohn Marino 	      (int) i, e->src->index, e->dest->index,
6614e4b17023SJohn Marino 	      (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
6615e4b17023SJohn Marino 	}
6616e4b17023SJohn Marino 
6617e4b17023SJohn Marino       if (e->flags & EDGE_EXECUTABLE)
6618e4b17023SJohn Marino 	{
6619e4b17023SJohn Marino 	  tree arg = PHI_ARG_DEF (phi, i);
6620e4b17023SJohn Marino 	  value_range_t vr_arg;
6621e4b17023SJohn Marino 
6622e4b17023SJohn Marino 	  ++edges;
6623e4b17023SJohn Marino 
6624e4b17023SJohn Marino 	  if (TREE_CODE (arg) == SSA_NAME)
6625e4b17023SJohn Marino 	    {
6626e4b17023SJohn Marino 	      vr_arg = *(get_value_range (arg));
66275ce9237cSJohn Marino 	      /* Do not allow equivalences or symbolic ranges to leak in from
66285ce9237cSJohn Marino 		 backedges.  That creates invalid equivalencies.  */
66295ce9237cSJohn Marino 	      if (e->flags & EDGE_DFS_BACK
66305ce9237cSJohn Marino 		  && (vr_arg.type == VR_RANGE
66315ce9237cSJohn Marino 		      || vr_arg.type == VR_ANTI_RANGE))
66325ce9237cSJohn Marino 		{
66335ce9237cSJohn Marino 		  vr_arg.equiv = NULL;
66345ce9237cSJohn Marino 		  if (symbolic_range_p (&vr_arg))
66355ce9237cSJohn Marino 		    {
66365ce9237cSJohn Marino 		      vr_arg.type = VR_VARYING;
66375ce9237cSJohn Marino 		      vr_arg.min = NULL_TREE;
66385ce9237cSJohn Marino 		      vr_arg.max = NULL_TREE;
66395ce9237cSJohn Marino 		    }
66405ce9237cSJohn Marino 		}
6641e4b17023SJohn Marino 	    }
6642e4b17023SJohn Marino 	  else
6643e4b17023SJohn Marino 	    {
6644e4b17023SJohn Marino 	      if (is_overflow_infinity (arg))
6645e4b17023SJohn Marino 		{
6646e4b17023SJohn Marino 		  arg = copy_node (arg);
6647e4b17023SJohn Marino 		  TREE_OVERFLOW (arg) = 0;
6648e4b17023SJohn Marino 		}
6649e4b17023SJohn Marino 
6650e4b17023SJohn Marino 	      vr_arg.type = VR_RANGE;
6651e4b17023SJohn Marino 	      vr_arg.min = arg;
6652e4b17023SJohn Marino 	      vr_arg.max = arg;
6653e4b17023SJohn Marino 	      vr_arg.equiv = NULL;
6654e4b17023SJohn Marino 	    }
6655e4b17023SJohn Marino 
6656e4b17023SJohn Marino 	  if (dump_file && (dump_flags & TDF_DETAILS))
6657e4b17023SJohn Marino 	    {
6658e4b17023SJohn Marino 	      fprintf (dump_file, "\t");
6659e4b17023SJohn Marino 	      print_generic_expr (dump_file, arg, dump_flags);
6660e4b17023SJohn Marino 	      fprintf (dump_file, "\n\tValue: ");
6661e4b17023SJohn Marino 	      dump_value_range (dump_file, &vr_arg);
6662e4b17023SJohn Marino 	      fprintf (dump_file, "\n");
6663e4b17023SJohn Marino 	    }
6664e4b17023SJohn Marino 
6665e4b17023SJohn Marino 	  if (first)
6666e4b17023SJohn Marino 	    copy_value_range (&vr_result, &vr_arg);
6667e4b17023SJohn Marino 	  else
6668e4b17023SJohn Marino 	    vrp_meet (&vr_result, &vr_arg);
6669e4b17023SJohn Marino 	  first = false;
6670e4b17023SJohn Marino 
6671e4b17023SJohn Marino 	  if (vr_result.type == VR_VARYING)
6672e4b17023SJohn Marino 	    break;
6673e4b17023SJohn Marino 	}
6674e4b17023SJohn Marino     }
6675e4b17023SJohn Marino 
6676e4b17023SJohn Marino   if (vr_result.type == VR_VARYING)
6677e4b17023SJohn Marino     goto varying;
6678e4b17023SJohn Marino   else if (vr_result.type == VR_UNDEFINED)
6679e4b17023SJohn Marino     goto update_range;
6680e4b17023SJohn Marino 
6681e4b17023SJohn Marino   old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
6682e4b17023SJohn Marino   vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
6683e4b17023SJohn Marino 
6684e4b17023SJohn Marino   /* To prevent infinite iterations in the algorithm, derive ranges
6685e4b17023SJohn Marino      when the new value is slightly bigger or smaller than the
6686e4b17023SJohn Marino      previous one.  We don't do this if we have seen a new executable
6687e4b17023SJohn Marino      edge; this helps us avoid an overflow infinity for conditionals
6688e4b17023SJohn Marino      which are not in a loop.  */
6689e4b17023SJohn Marino   if (edges > 0
6690e4b17023SJohn Marino       && gimple_phi_num_args (phi) > 1
6691e4b17023SJohn Marino       && edges == old_edges)
6692e4b17023SJohn Marino     {
6693e4b17023SJohn Marino       int cmp_min = compare_values (lhs_vr->min, vr_result.min);
6694e4b17023SJohn Marino       int cmp_max = compare_values (lhs_vr->max, vr_result.max);
6695e4b17023SJohn Marino 
6696e4b17023SJohn Marino       /* For non VR_RANGE or for pointers fall back to varying if
6697e4b17023SJohn Marino 	 the range changed.  */
6698e4b17023SJohn Marino       if ((lhs_vr->type != VR_RANGE || vr_result.type != VR_RANGE
6699e4b17023SJohn Marino 	   || POINTER_TYPE_P (TREE_TYPE (lhs)))
6700e4b17023SJohn Marino 	  && (cmp_min != 0 || cmp_max != 0))
6701e4b17023SJohn Marino 	goto varying;
6702e4b17023SJohn Marino 
6703e4b17023SJohn Marino       /* If the new minimum is smaller or larger than the previous
6704e4b17023SJohn Marino 	 one, go all the way to -INF.  In the first case, to avoid
6705e4b17023SJohn Marino 	 iterating millions of times to reach -INF, and in the
6706e4b17023SJohn Marino 	 other case to avoid infinite bouncing between different
6707e4b17023SJohn Marino 	 minimums.  */
6708e4b17023SJohn Marino       if (cmp_min > 0 || cmp_min < 0)
6709e4b17023SJohn Marino 	{
6710e4b17023SJohn Marino 	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
6711e4b17023SJohn Marino 	      || !vrp_var_may_overflow (lhs, phi))
6712e4b17023SJohn Marino 	    vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
6713e4b17023SJohn Marino 	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
6714e4b17023SJohn Marino 	    vr_result.min =
6715e4b17023SJohn Marino 		negative_overflow_infinity (TREE_TYPE (vr_result.min));
6716e4b17023SJohn Marino 	}
6717e4b17023SJohn Marino 
6718e4b17023SJohn Marino       /* Similarly, if the new maximum is smaller or larger than
6719e4b17023SJohn Marino 	 the previous one, go all the way to +INF.  */
6720e4b17023SJohn Marino       if (cmp_max < 0 || cmp_max > 0)
6721e4b17023SJohn Marino 	{
6722e4b17023SJohn Marino 	  if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
6723e4b17023SJohn Marino 	      || !vrp_var_may_overflow (lhs, phi))
6724e4b17023SJohn Marino 	    vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
6725e4b17023SJohn Marino 	  else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
6726e4b17023SJohn Marino 	    vr_result.max =
6727e4b17023SJohn Marino 		positive_overflow_infinity (TREE_TYPE (vr_result.max));
6728e4b17023SJohn Marino 	}
6729e4b17023SJohn Marino 
6730e4b17023SJohn Marino       /* If we dropped either bound to +-INF then if this is a loop
6731e4b17023SJohn Marino 	 PHI node SCEV may known more about its value-range.  */
6732e4b17023SJohn Marino       if ((cmp_min > 0 || cmp_min < 0
6733e4b17023SJohn Marino 	   || cmp_max < 0 || cmp_max > 0)
6734e4b17023SJohn Marino 	  && current_loops
6735e4b17023SJohn Marino 	  && (l = loop_containing_stmt (phi))
6736e4b17023SJohn Marino 	  && l->header == gimple_bb (phi))
6737e4b17023SJohn Marino 	adjust_range_with_scev (&vr_result, l, phi, lhs);
6738e4b17023SJohn Marino 
6739e4b17023SJohn Marino       /* If we will end up with a (-INF, +INF) range, set it to
6740e4b17023SJohn Marino 	 VARYING.  Same if the previous max value was invalid for
6741e4b17023SJohn Marino 	 the type and we end up with vr_result.min > vr_result.max.  */
6742e4b17023SJohn Marino       if ((vrp_val_is_max (vr_result.max)
6743e4b17023SJohn Marino 	   && vrp_val_is_min (vr_result.min))
6744e4b17023SJohn Marino 	  || compare_values (vr_result.min,
6745e4b17023SJohn Marino 			     vr_result.max) > 0)
6746e4b17023SJohn Marino 	goto varying;
6747e4b17023SJohn Marino     }
6748e4b17023SJohn Marino 
6749e4b17023SJohn Marino   /* If the new range is different than the previous value, keep
6750e4b17023SJohn Marino      iterating.  */
6751e4b17023SJohn Marino update_range:
6752e4b17023SJohn Marino   if (update_value_range (lhs, &vr_result))
6753e4b17023SJohn Marino     {
6754e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
6755e4b17023SJohn Marino 	{
6756e4b17023SJohn Marino 	  fprintf (dump_file, "Found new range for ");
6757e4b17023SJohn Marino 	  print_generic_expr (dump_file, lhs, 0);
6758e4b17023SJohn Marino 	  fprintf (dump_file, ": ");
6759e4b17023SJohn Marino 	  dump_value_range (dump_file, &vr_result);
6760e4b17023SJohn Marino 	  fprintf (dump_file, "\n\n");
6761e4b17023SJohn Marino 	}
6762e4b17023SJohn Marino 
6763e4b17023SJohn Marino       return SSA_PROP_INTERESTING;
6764e4b17023SJohn Marino     }
6765e4b17023SJohn Marino 
6766e4b17023SJohn Marino   /* Nothing changed, don't add outgoing edges.  */
6767e4b17023SJohn Marino   return SSA_PROP_NOT_INTERESTING;
6768e4b17023SJohn Marino 
6769e4b17023SJohn Marino   /* No match found.  Set the LHS to VARYING.  */
6770e4b17023SJohn Marino varying:
6771e4b17023SJohn Marino   set_value_range_to_varying (lhs_vr);
6772e4b17023SJohn Marino   return SSA_PROP_VARYING;
6773e4b17023SJohn Marino }
6774e4b17023SJohn Marino 
6775e4b17023SJohn Marino /* Simplify boolean operations if the source is known
6776e4b17023SJohn Marino    to be already a boolean.  */
6777e4b17023SJohn Marino static bool
simplify_truth_ops_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)6778e4b17023SJohn Marino simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
6779e4b17023SJohn Marino {
6780e4b17023SJohn Marino   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
6781e4b17023SJohn Marino   tree lhs, op0, op1;
6782e4b17023SJohn Marino   bool need_conversion;
6783e4b17023SJohn Marino 
6784e4b17023SJohn Marino   /* We handle only !=/== case here.  */
6785e4b17023SJohn Marino   gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
6786e4b17023SJohn Marino 
6787e4b17023SJohn Marino   op0 = gimple_assign_rhs1 (stmt);
6788e4b17023SJohn Marino   if (!op_with_boolean_value_range_p (op0))
6789e4b17023SJohn Marino     return false;
6790e4b17023SJohn Marino 
6791e4b17023SJohn Marino   op1 = gimple_assign_rhs2 (stmt);
6792e4b17023SJohn Marino   if (!op_with_boolean_value_range_p (op1))
6793e4b17023SJohn Marino     return false;
6794e4b17023SJohn Marino 
6795e4b17023SJohn Marino   /* Reduce number of cases to handle to NE_EXPR.  As there is no
6796e4b17023SJohn Marino      BIT_XNOR_EXPR we cannot replace A == B with a single statement.  */
6797e4b17023SJohn Marino   if (rhs_code == EQ_EXPR)
6798e4b17023SJohn Marino     {
6799e4b17023SJohn Marino       if (TREE_CODE (op1) == INTEGER_CST)
6800e4b17023SJohn Marino 	op1 = int_const_binop (BIT_XOR_EXPR, op1, integer_one_node);
6801e4b17023SJohn Marino       else
6802e4b17023SJohn Marino 	return false;
6803e4b17023SJohn Marino     }
6804e4b17023SJohn Marino 
6805e4b17023SJohn Marino   lhs = gimple_assign_lhs (stmt);
6806e4b17023SJohn Marino   need_conversion
6807e4b17023SJohn Marino     = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
6808e4b17023SJohn Marino 
6809e4b17023SJohn Marino   /* Make sure to not sign-extend a 1-bit 1 when converting the result.  */
6810e4b17023SJohn Marino   if (need_conversion
6811e4b17023SJohn Marino       && !TYPE_UNSIGNED (TREE_TYPE (op0))
6812e4b17023SJohn Marino       && TYPE_PRECISION (TREE_TYPE (op0)) == 1
6813e4b17023SJohn Marino       && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
6814e4b17023SJohn Marino     return false;
6815e4b17023SJohn Marino 
6816e4b17023SJohn Marino   /* For A != 0 we can substitute A itself.  */
6817e4b17023SJohn Marino   if (integer_zerop (op1))
6818e4b17023SJohn Marino     gimple_assign_set_rhs_with_ops (gsi,
6819e4b17023SJohn Marino 				    need_conversion
6820e4b17023SJohn Marino 				    ? NOP_EXPR : TREE_CODE (op0),
6821e4b17023SJohn Marino 				    op0, NULL_TREE);
6822e4b17023SJohn Marino   /* For A != B we substitute A ^ B.  Either with conversion.  */
6823e4b17023SJohn Marino   else if (need_conversion)
6824e4b17023SJohn Marino     {
6825e4b17023SJohn Marino       gimple newop;
6826e4b17023SJohn Marino       tree tem = create_tmp_reg (TREE_TYPE (op0), NULL);
6827e4b17023SJohn Marino       newop = gimple_build_assign_with_ops (BIT_XOR_EXPR, tem, op0, op1);
6828e4b17023SJohn Marino       tem = make_ssa_name (tem, newop);
6829e4b17023SJohn Marino       gimple_assign_set_lhs (newop, tem);
6830e4b17023SJohn Marino       gsi_insert_before (gsi, newop, GSI_SAME_STMT);
6831e4b17023SJohn Marino       update_stmt (newop);
6832e4b17023SJohn Marino       gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem, NULL_TREE);
6833e4b17023SJohn Marino     }
6834e4b17023SJohn Marino   /* Or without.  */
6835e4b17023SJohn Marino   else
6836e4b17023SJohn Marino     gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
6837e4b17023SJohn Marino   update_stmt (gsi_stmt (*gsi));
6838e4b17023SJohn Marino 
6839e4b17023SJohn Marino   return true;
6840e4b17023SJohn Marino }
6841e4b17023SJohn Marino 
6842e4b17023SJohn Marino /* Simplify a division or modulo operator to a right shift or
6843e4b17023SJohn Marino    bitwise and if the first operand is unsigned or is greater
6844e4b17023SJohn Marino    than zero and the second operand is an exact power of two.  */
6845e4b17023SJohn Marino 
6846e4b17023SJohn Marino static bool
simplify_div_or_mod_using_ranges(gimple stmt)6847e4b17023SJohn Marino simplify_div_or_mod_using_ranges (gimple stmt)
6848e4b17023SJohn Marino {
6849e4b17023SJohn Marino   enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
6850e4b17023SJohn Marino   tree val = NULL;
6851e4b17023SJohn Marino   tree op0 = gimple_assign_rhs1 (stmt);
6852e4b17023SJohn Marino   tree op1 = gimple_assign_rhs2 (stmt);
6853e4b17023SJohn Marino   value_range_t *vr = get_value_range (gimple_assign_rhs1 (stmt));
6854e4b17023SJohn Marino 
6855e4b17023SJohn Marino   if (TYPE_UNSIGNED (TREE_TYPE (op0)))
6856e4b17023SJohn Marino     {
6857e4b17023SJohn Marino       val = integer_one_node;
6858e4b17023SJohn Marino     }
6859e4b17023SJohn Marino   else
6860e4b17023SJohn Marino     {
6861e4b17023SJohn Marino       bool sop = false;
6862e4b17023SJohn Marino 
6863e4b17023SJohn Marino       val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);
6864e4b17023SJohn Marino 
6865e4b17023SJohn Marino       if (val
6866e4b17023SJohn Marino 	  && sop
6867e4b17023SJohn Marino 	  && integer_onep (val)
6868e4b17023SJohn Marino 	  && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
6869e4b17023SJohn Marino 	{
6870e4b17023SJohn Marino 	  location_t location;
6871e4b17023SJohn Marino 
6872e4b17023SJohn Marino 	  if (!gimple_has_location (stmt))
6873e4b17023SJohn Marino 	    location = input_location;
6874e4b17023SJohn Marino 	  else
6875e4b17023SJohn Marino 	    location = gimple_location (stmt);
6876e4b17023SJohn Marino 	  warning_at (location, OPT_Wstrict_overflow,
6877e4b17023SJohn Marino 		      "assuming signed overflow does not occur when "
6878e4b17023SJohn Marino 		      "simplifying %</%> or %<%%%> to %<>>%> or %<&%>");
6879e4b17023SJohn Marino 	}
6880e4b17023SJohn Marino     }
6881e4b17023SJohn Marino 
6882e4b17023SJohn Marino   if (val && integer_onep (val))
6883e4b17023SJohn Marino     {
6884e4b17023SJohn Marino       tree t;
6885e4b17023SJohn Marino 
6886e4b17023SJohn Marino       if (rhs_code == TRUNC_DIV_EXPR)
6887e4b17023SJohn Marino 	{
6888e4b17023SJohn Marino 	  t = build_int_cst (integer_type_node, tree_log2 (op1));
6889e4b17023SJohn Marino 	  gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
6890e4b17023SJohn Marino 	  gimple_assign_set_rhs1 (stmt, op0);
6891e4b17023SJohn Marino 	  gimple_assign_set_rhs2 (stmt, t);
6892e4b17023SJohn Marino 	}
6893e4b17023SJohn Marino       else
6894e4b17023SJohn Marino 	{
6895e4b17023SJohn Marino 	  t = build_int_cst (TREE_TYPE (op1), 1);
6896e4b17023SJohn Marino 	  t = int_const_binop (MINUS_EXPR, op1, t);
6897e4b17023SJohn Marino 	  t = fold_convert (TREE_TYPE (op0), t);
6898e4b17023SJohn Marino 
6899e4b17023SJohn Marino 	  gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
6900e4b17023SJohn Marino 	  gimple_assign_set_rhs1 (stmt, op0);
6901e4b17023SJohn Marino 	  gimple_assign_set_rhs2 (stmt, t);
6902e4b17023SJohn Marino 	}
6903e4b17023SJohn Marino 
6904e4b17023SJohn Marino       update_stmt (stmt);
6905e4b17023SJohn Marino       return true;
6906e4b17023SJohn Marino     }
6907e4b17023SJohn Marino 
6908e4b17023SJohn Marino   return false;
6909e4b17023SJohn Marino }
6910e4b17023SJohn Marino 
6911e4b17023SJohn Marino /* If the operand to an ABS_EXPR is >= 0, then eliminate the
6912e4b17023SJohn Marino    ABS_EXPR.  If the operand is <= 0, then simplify the
6913e4b17023SJohn Marino    ABS_EXPR into a NEGATE_EXPR.  */
6914e4b17023SJohn Marino 
6915e4b17023SJohn Marino static bool
simplify_abs_using_ranges(gimple stmt)6916e4b17023SJohn Marino simplify_abs_using_ranges (gimple stmt)
6917e4b17023SJohn Marino {
6918e4b17023SJohn Marino   tree val = NULL;
6919e4b17023SJohn Marino   tree op = gimple_assign_rhs1 (stmt);
6920e4b17023SJohn Marino   tree type = TREE_TYPE (op);
6921e4b17023SJohn Marino   value_range_t *vr = get_value_range (op);
6922e4b17023SJohn Marino 
6923e4b17023SJohn Marino   if (TYPE_UNSIGNED (type))
6924e4b17023SJohn Marino     {
6925e4b17023SJohn Marino       val = integer_zero_node;
6926e4b17023SJohn Marino     }
6927e4b17023SJohn Marino   else if (vr)
6928e4b17023SJohn Marino     {
6929e4b17023SJohn Marino       bool sop = false;
6930e4b17023SJohn Marino 
6931e4b17023SJohn Marino       val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
6932e4b17023SJohn Marino       if (!val)
6933e4b17023SJohn Marino 	{
6934e4b17023SJohn Marino 	  sop = false;
6935e4b17023SJohn Marino 	  val = compare_range_with_value (GE_EXPR, vr, integer_zero_node,
6936e4b17023SJohn Marino 					  &sop);
6937e4b17023SJohn Marino 
6938e4b17023SJohn Marino 	  if (val)
6939e4b17023SJohn Marino 	    {
6940e4b17023SJohn Marino 	      if (integer_zerop (val))
6941e4b17023SJohn Marino 		val = integer_one_node;
6942e4b17023SJohn Marino 	      else if (integer_onep (val))
6943e4b17023SJohn Marino 		val = integer_zero_node;
6944e4b17023SJohn Marino 	    }
6945e4b17023SJohn Marino 	}
6946e4b17023SJohn Marino 
6947e4b17023SJohn Marino       if (val
6948e4b17023SJohn Marino 	  && (integer_onep (val) || integer_zerop (val)))
6949e4b17023SJohn Marino 	{
6950e4b17023SJohn Marino 	  if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
6951e4b17023SJohn Marino 	    {
6952e4b17023SJohn Marino 	      location_t location;
6953e4b17023SJohn Marino 
6954e4b17023SJohn Marino 	      if (!gimple_has_location (stmt))
6955e4b17023SJohn Marino 		location = input_location;
6956e4b17023SJohn Marino 	      else
6957e4b17023SJohn Marino 		location = gimple_location (stmt);
6958e4b17023SJohn Marino 	      warning_at (location, OPT_Wstrict_overflow,
6959e4b17023SJohn Marino 			  "assuming signed overflow does not occur when "
6960e4b17023SJohn Marino 			  "simplifying %<abs (X)%> to %<X%> or %<-X%>");
6961e4b17023SJohn Marino 	    }
6962e4b17023SJohn Marino 
6963e4b17023SJohn Marino 	  gimple_assign_set_rhs1 (stmt, op);
6964e4b17023SJohn Marino 	  if (integer_onep (val))
6965e4b17023SJohn Marino 	    gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
6966e4b17023SJohn Marino 	  else
6967e4b17023SJohn Marino 	    gimple_assign_set_rhs_code (stmt, SSA_NAME);
6968e4b17023SJohn Marino 	  update_stmt (stmt);
6969e4b17023SJohn Marino 	  return true;
6970e4b17023SJohn Marino 	}
6971e4b17023SJohn Marino     }
6972e4b17023SJohn Marino 
6973e4b17023SJohn Marino   return false;
6974e4b17023SJohn Marino }
6975e4b17023SJohn Marino 
6976e4b17023SJohn Marino /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
6977e4b17023SJohn Marino    If all the bits that are being cleared by & are already
6978e4b17023SJohn Marino    known to be zero from VR, or all the bits that are being
6979e4b17023SJohn Marino    set by | are already known to be one from VR, the bit
6980e4b17023SJohn Marino    operation is redundant.  */
6981e4b17023SJohn Marino 
6982e4b17023SJohn Marino static bool
simplify_bit_ops_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)6983e4b17023SJohn Marino simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
6984e4b17023SJohn Marino {
6985e4b17023SJohn Marino   tree op0 = gimple_assign_rhs1 (stmt);
6986e4b17023SJohn Marino   tree op1 = gimple_assign_rhs2 (stmt);
6987e4b17023SJohn Marino   tree op = NULL_TREE;
6988e4b17023SJohn Marino   value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6989e4b17023SJohn Marino   value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6990e4b17023SJohn Marino   double_int may_be_nonzero0, may_be_nonzero1;
6991e4b17023SJohn Marino   double_int must_be_nonzero0, must_be_nonzero1;
6992e4b17023SJohn Marino   double_int mask;
6993e4b17023SJohn Marino 
6994e4b17023SJohn Marino   if (TREE_CODE (op0) == SSA_NAME)
6995e4b17023SJohn Marino     vr0 = *(get_value_range (op0));
6996e4b17023SJohn Marino   else if (is_gimple_min_invariant (op0))
6997e4b17023SJohn Marino     set_value_range_to_value (&vr0, op0, NULL);
6998e4b17023SJohn Marino   else
6999e4b17023SJohn Marino     return false;
7000e4b17023SJohn Marino 
7001e4b17023SJohn Marino   if (TREE_CODE (op1) == SSA_NAME)
7002e4b17023SJohn Marino     vr1 = *(get_value_range (op1));
7003e4b17023SJohn Marino   else if (is_gimple_min_invariant (op1))
7004e4b17023SJohn Marino     set_value_range_to_value (&vr1, op1, NULL);
7005e4b17023SJohn Marino   else
7006e4b17023SJohn Marino     return false;
7007e4b17023SJohn Marino 
7008e4b17023SJohn Marino   if (!zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0, &must_be_nonzero0))
7009e4b17023SJohn Marino     return false;
7010e4b17023SJohn Marino   if (!zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1, &must_be_nonzero1))
7011e4b17023SJohn Marino     return false;
7012e4b17023SJohn Marino 
7013e4b17023SJohn Marino   switch (gimple_assign_rhs_code (stmt))
7014e4b17023SJohn Marino     {
7015e4b17023SJohn Marino     case BIT_AND_EXPR:
7016e4b17023SJohn Marino       mask = double_int_and_not (may_be_nonzero0, must_be_nonzero1);
7017e4b17023SJohn Marino       if (double_int_zero_p (mask))
7018e4b17023SJohn Marino 	{
7019e4b17023SJohn Marino 	  op = op0;
7020e4b17023SJohn Marino 	  break;
7021e4b17023SJohn Marino 	}
7022e4b17023SJohn Marino       mask = double_int_and_not (may_be_nonzero1, must_be_nonzero0);
7023e4b17023SJohn Marino       if (double_int_zero_p (mask))
7024e4b17023SJohn Marino 	{
7025e4b17023SJohn Marino 	  op = op1;
7026e4b17023SJohn Marino 	  break;
7027e4b17023SJohn Marino 	}
7028e4b17023SJohn Marino       break;
7029e4b17023SJohn Marino     case BIT_IOR_EXPR:
7030e4b17023SJohn Marino       mask = double_int_and_not (may_be_nonzero0, must_be_nonzero1);
7031e4b17023SJohn Marino       if (double_int_zero_p (mask))
7032e4b17023SJohn Marino 	{
7033e4b17023SJohn Marino 	  op = op1;
7034e4b17023SJohn Marino 	  break;
7035e4b17023SJohn Marino 	}
7036e4b17023SJohn Marino       mask = double_int_and_not (may_be_nonzero1, must_be_nonzero0);
7037e4b17023SJohn Marino       if (double_int_zero_p (mask))
7038e4b17023SJohn Marino 	{
7039e4b17023SJohn Marino 	  op = op0;
7040e4b17023SJohn Marino 	  break;
7041e4b17023SJohn Marino 	}
7042e4b17023SJohn Marino       break;
7043e4b17023SJohn Marino     default:
7044e4b17023SJohn Marino       gcc_unreachable ();
7045e4b17023SJohn Marino     }
7046e4b17023SJohn Marino 
7047e4b17023SJohn Marino   if (op == NULL_TREE)
7048e4b17023SJohn Marino     return false;
7049e4b17023SJohn Marino 
7050e4b17023SJohn Marino   gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op, NULL);
7051e4b17023SJohn Marino   update_stmt (gsi_stmt (*gsi));
7052e4b17023SJohn Marino   return true;
7053e4b17023SJohn Marino }
7054e4b17023SJohn Marino 
7055e4b17023SJohn Marino /* We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
7056e4b17023SJohn Marino    a known value range VR.
7057e4b17023SJohn Marino 
7058e4b17023SJohn Marino    If there is one and only one value which will satisfy the
7059e4b17023SJohn Marino    conditional, then return that value.  Else return NULL.  */
7060e4b17023SJohn Marino 
7061e4b17023SJohn Marino static tree
test_for_singularity(enum tree_code cond_code,tree op0,tree op1,value_range_t * vr)7062e4b17023SJohn Marino test_for_singularity (enum tree_code cond_code, tree op0,
7063e4b17023SJohn Marino 		      tree op1, value_range_t *vr)
7064e4b17023SJohn Marino {
7065e4b17023SJohn Marino   tree min = NULL;
7066e4b17023SJohn Marino   tree max = NULL;
7067e4b17023SJohn Marino 
7068e4b17023SJohn Marino   /* Extract minimum/maximum values which satisfy the
7069e4b17023SJohn Marino      the conditional as it was written.  */
7070e4b17023SJohn Marino   if (cond_code == LE_EXPR || cond_code == LT_EXPR)
7071e4b17023SJohn Marino     {
7072e4b17023SJohn Marino       /* This should not be negative infinity; there is no overflow
7073e4b17023SJohn Marino 	 here.  */
7074e4b17023SJohn Marino       min = TYPE_MIN_VALUE (TREE_TYPE (op0));
7075e4b17023SJohn Marino 
7076e4b17023SJohn Marino       max = op1;
7077e4b17023SJohn Marino       if (cond_code == LT_EXPR && !is_overflow_infinity (max))
7078e4b17023SJohn Marino 	{
7079e4b17023SJohn Marino 	  tree one = build_int_cst (TREE_TYPE (op0), 1);
7080e4b17023SJohn Marino 	  max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
7081e4b17023SJohn Marino 	  if (EXPR_P (max))
7082e4b17023SJohn Marino 	    TREE_NO_WARNING (max) = 1;
7083e4b17023SJohn Marino 	}
7084e4b17023SJohn Marino     }
7085e4b17023SJohn Marino   else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
7086e4b17023SJohn Marino     {
7087e4b17023SJohn Marino       /* This should not be positive infinity; there is no overflow
7088e4b17023SJohn Marino 	 here.  */
7089e4b17023SJohn Marino       max = TYPE_MAX_VALUE (TREE_TYPE (op0));
7090e4b17023SJohn Marino 
7091e4b17023SJohn Marino       min = op1;
7092e4b17023SJohn Marino       if (cond_code == GT_EXPR && !is_overflow_infinity (min))
7093e4b17023SJohn Marino 	{
7094e4b17023SJohn Marino 	  tree one = build_int_cst (TREE_TYPE (op0), 1);
7095e4b17023SJohn Marino 	  min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
7096e4b17023SJohn Marino 	  if (EXPR_P (min))
7097e4b17023SJohn Marino 	    TREE_NO_WARNING (min) = 1;
7098e4b17023SJohn Marino 	}
7099e4b17023SJohn Marino     }
7100e4b17023SJohn Marino 
7101e4b17023SJohn Marino   /* Now refine the minimum and maximum values using any
7102e4b17023SJohn Marino      value range information we have for op0.  */
7103e4b17023SJohn Marino   if (min && max)
7104e4b17023SJohn Marino     {
7105e4b17023SJohn Marino       if (compare_values (vr->min, min) == 1)
7106e4b17023SJohn Marino 	min = vr->min;
7107e4b17023SJohn Marino       if (compare_values (vr->max, max) == -1)
7108e4b17023SJohn Marino 	max = vr->max;
7109e4b17023SJohn Marino 
7110e4b17023SJohn Marino       /* If the new min/max values have converged to a single value,
7111e4b17023SJohn Marino 	 then there is only one value which can satisfy the condition,
7112e4b17023SJohn Marino 	 return that value.  */
7113e4b17023SJohn Marino       if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
7114e4b17023SJohn Marino 	return min;
7115e4b17023SJohn Marino     }
7116e4b17023SJohn Marino   return NULL;
7117e4b17023SJohn Marino }
7118e4b17023SJohn Marino 
7119e4b17023SJohn Marino /* Simplify a conditional using a relational operator to an equality
7120e4b17023SJohn Marino    test if the range information indicates only one value can satisfy
7121e4b17023SJohn Marino    the original conditional.  */
7122e4b17023SJohn Marino 
7123e4b17023SJohn Marino static bool
simplify_cond_using_ranges(gimple stmt)7124e4b17023SJohn Marino simplify_cond_using_ranges (gimple stmt)
7125e4b17023SJohn Marino {
7126e4b17023SJohn Marino   tree op0 = gimple_cond_lhs (stmt);
7127e4b17023SJohn Marino   tree op1 = gimple_cond_rhs (stmt);
7128e4b17023SJohn Marino   enum tree_code cond_code = gimple_cond_code (stmt);
7129e4b17023SJohn Marino 
7130e4b17023SJohn Marino   if (cond_code != NE_EXPR
7131e4b17023SJohn Marino       && cond_code != EQ_EXPR
7132e4b17023SJohn Marino       && TREE_CODE (op0) == SSA_NAME
7133e4b17023SJohn Marino       && INTEGRAL_TYPE_P (TREE_TYPE (op0))
7134e4b17023SJohn Marino       && is_gimple_min_invariant (op1))
7135e4b17023SJohn Marino     {
7136e4b17023SJohn Marino       value_range_t *vr = get_value_range (op0);
7137e4b17023SJohn Marino 
7138e4b17023SJohn Marino       /* If we have range information for OP0, then we might be
7139e4b17023SJohn Marino 	 able to simplify this conditional. */
7140e4b17023SJohn Marino       if (vr->type == VR_RANGE)
7141e4b17023SJohn Marino 	{
7142e4b17023SJohn Marino 	  tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
7143e4b17023SJohn Marino 
7144e4b17023SJohn Marino 	  if (new_tree)
7145e4b17023SJohn Marino 	    {
7146e4b17023SJohn Marino 	      if (dump_file)
7147e4b17023SJohn Marino 		{
7148e4b17023SJohn Marino 		  fprintf (dump_file, "Simplified relational ");
7149e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, 0);
7150e4b17023SJohn Marino 		  fprintf (dump_file, " into ");
7151e4b17023SJohn Marino 		}
7152e4b17023SJohn Marino 
7153e4b17023SJohn Marino 	      gimple_cond_set_code (stmt, EQ_EXPR);
7154e4b17023SJohn Marino 	      gimple_cond_set_lhs (stmt, op0);
7155e4b17023SJohn Marino 	      gimple_cond_set_rhs (stmt, new_tree);
7156e4b17023SJohn Marino 
7157e4b17023SJohn Marino 	      update_stmt (stmt);
7158e4b17023SJohn Marino 
7159e4b17023SJohn Marino 	      if (dump_file)
7160e4b17023SJohn Marino 		{
7161e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, 0);
7162e4b17023SJohn Marino 		  fprintf (dump_file, "\n");
7163e4b17023SJohn Marino 		}
7164e4b17023SJohn Marino 
7165e4b17023SJohn Marino 	      return true;
7166e4b17023SJohn Marino 	    }
7167e4b17023SJohn Marino 
7168e4b17023SJohn Marino 	  /* Try again after inverting the condition.  We only deal
7169e4b17023SJohn Marino 	     with integral types here, so no need to worry about
7170e4b17023SJohn Marino 	     issues with inverting FP comparisons.  */
7171e4b17023SJohn Marino 	  cond_code = invert_tree_comparison (cond_code, false);
7172e4b17023SJohn Marino 	  new_tree = test_for_singularity (cond_code, op0, op1, vr);
7173e4b17023SJohn Marino 
7174e4b17023SJohn Marino 	  if (new_tree)
7175e4b17023SJohn Marino 	    {
7176e4b17023SJohn Marino 	      if (dump_file)
7177e4b17023SJohn Marino 		{
7178e4b17023SJohn Marino 		  fprintf (dump_file, "Simplified relational ");
7179e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, 0);
7180e4b17023SJohn Marino 		  fprintf (dump_file, " into ");
7181e4b17023SJohn Marino 		}
7182e4b17023SJohn Marino 
7183e4b17023SJohn Marino 	      gimple_cond_set_code (stmt, NE_EXPR);
7184e4b17023SJohn Marino 	      gimple_cond_set_lhs (stmt, op0);
7185e4b17023SJohn Marino 	      gimple_cond_set_rhs (stmt, new_tree);
7186e4b17023SJohn Marino 
7187e4b17023SJohn Marino 	      update_stmt (stmt);
7188e4b17023SJohn Marino 
7189e4b17023SJohn Marino 	      if (dump_file)
7190e4b17023SJohn Marino 		{
7191e4b17023SJohn Marino 		  print_gimple_stmt (dump_file, stmt, 0, 0);
7192e4b17023SJohn Marino 		  fprintf (dump_file, "\n");
7193e4b17023SJohn Marino 		}
7194e4b17023SJohn Marino 
7195e4b17023SJohn Marino 	      return true;
7196e4b17023SJohn Marino 	    }
7197e4b17023SJohn Marino 	}
7198e4b17023SJohn Marino     }
7199e4b17023SJohn Marino 
7200e4b17023SJohn Marino   return false;
7201e4b17023SJohn Marino }
7202e4b17023SJohn Marino 
7203e4b17023SJohn Marino /* Simplify a switch statement using the value range of the switch
7204e4b17023SJohn Marino    argument.  */
7205e4b17023SJohn Marino 
7206e4b17023SJohn Marino static bool
simplify_switch_using_ranges(gimple stmt)7207e4b17023SJohn Marino simplify_switch_using_ranges (gimple stmt)
7208e4b17023SJohn Marino {
7209e4b17023SJohn Marino   tree op = gimple_switch_index (stmt);
7210e4b17023SJohn Marino   value_range_t *vr;
7211e4b17023SJohn Marino   bool take_default;
7212e4b17023SJohn Marino   edge e;
7213e4b17023SJohn Marino   edge_iterator ei;
7214e4b17023SJohn Marino   size_t i = 0, j = 0, n, n2;
7215e4b17023SJohn Marino   tree vec2;
7216e4b17023SJohn Marino   switch_update su;
7217e4b17023SJohn Marino 
7218e4b17023SJohn Marino   if (TREE_CODE (op) == SSA_NAME)
7219e4b17023SJohn Marino     {
7220e4b17023SJohn Marino       vr = get_value_range (op);
7221e4b17023SJohn Marino 
7222e4b17023SJohn Marino       /* We can only handle integer ranges.  */
7223e4b17023SJohn Marino       if (vr->type != VR_RANGE
7224e4b17023SJohn Marino 	  || symbolic_range_p (vr))
7225e4b17023SJohn Marino 	return false;
7226e4b17023SJohn Marino 
7227e4b17023SJohn Marino       /* Find case label for min/max of the value range.  */
7228e4b17023SJohn Marino       take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
7229e4b17023SJohn Marino     }
7230e4b17023SJohn Marino   else if (TREE_CODE (op) == INTEGER_CST)
7231e4b17023SJohn Marino     {
7232e4b17023SJohn Marino       take_default = !find_case_label_index (stmt, 1, op, &i);
7233e4b17023SJohn Marino       if (take_default)
7234e4b17023SJohn Marino 	{
7235e4b17023SJohn Marino 	  i = 1;
7236e4b17023SJohn Marino 	  j = 0;
7237e4b17023SJohn Marino 	}
7238e4b17023SJohn Marino       else
7239e4b17023SJohn Marino 	{
7240e4b17023SJohn Marino 	  j = i;
7241e4b17023SJohn Marino 	}
7242e4b17023SJohn Marino     }
7243e4b17023SJohn Marino   else
7244e4b17023SJohn Marino     return false;
7245e4b17023SJohn Marino 
7246e4b17023SJohn Marino   n = gimple_switch_num_labels (stmt);
7247e4b17023SJohn Marino 
7248e4b17023SJohn Marino   /* Bail out if this is just all edges taken.  */
7249e4b17023SJohn Marino   if (i == 1
7250e4b17023SJohn Marino       && j == n - 1
7251e4b17023SJohn Marino       && take_default)
7252e4b17023SJohn Marino     return false;
7253e4b17023SJohn Marino 
7254e4b17023SJohn Marino   /* Build a new vector of taken case labels.  */
7255e4b17023SJohn Marino   vec2 = make_tree_vec (j - i + 1 + (int)take_default);
7256e4b17023SJohn Marino   n2 = 0;
7257e4b17023SJohn Marino 
7258e4b17023SJohn Marino   /* Add the default edge, if necessary.  */
7259e4b17023SJohn Marino   if (take_default)
7260e4b17023SJohn Marino     TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
7261e4b17023SJohn Marino 
7262e4b17023SJohn Marino   for (; i <= j; ++i, ++n2)
7263e4b17023SJohn Marino     TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
7264e4b17023SJohn Marino 
7265e4b17023SJohn Marino   /* Mark needed edges.  */
7266e4b17023SJohn Marino   for (i = 0; i < n2; ++i)
7267e4b17023SJohn Marino     {
7268e4b17023SJohn Marino       e = find_edge (gimple_bb (stmt),
7269e4b17023SJohn Marino 		     label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i))));
7270e4b17023SJohn Marino       e->aux = (void *)-1;
7271e4b17023SJohn Marino     }
7272e4b17023SJohn Marino 
7273e4b17023SJohn Marino   /* Queue not needed edges for later removal.  */
7274e4b17023SJohn Marino   FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
7275e4b17023SJohn Marino     {
7276e4b17023SJohn Marino       if (e->aux == (void *)-1)
7277e4b17023SJohn Marino 	{
7278e4b17023SJohn Marino 	  e->aux = NULL;
7279e4b17023SJohn Marino 	  continue;
7280e4b17023SJohn Marino 	}
7281e4b17023SJohn Marino 
7282e4b17023SJohn Marino       if (dump_file && (dump_flags & TDF_DETAILS))
7283e4b17023SJohn Marino 	{
7284e4b17023SJohn Marino 	  fprintf (dump_file, "removing unreachable case label\n");
7285e4b17023SJohn Marino 	}
7286e4b17023SJohn Marino       VEC_safe_push (edge, heap, to_remove_edges, e);
7287e4b17023SJohn Marino       e->flags &= ~EDGE_EXECUTABLE;
7288e4b17023SJohn Marino     }
7289e4b17023SJohn Marino 
7290e4b17023SJohn Marino   /* And queue an update for the stmt.  */
7291e4b17023SJohn Marino   su.stmt = stmt;
7292e4b17023SJohn Marino   su.vec = vec2;
7293e4b17023SJohn Marino   VEC_safe_push (switch_update, heap, to_update_switch_stmts, &su);
7294e4b17023SJohn Marino   return false;
7295e4b17023SJohn Marino }
7296e4b17023SJohn Marino 
7297e4b17023SJohn Marino /* Simplify an integral conversion from an SSA name in STMT.  */
7298e4b17023SJohn Marino 
7299e4b17023SJohn Marino static bool
simplify_conversion_using_ranges(gimple stmt)7300e4b17023SJohn Marino simplify_conversion_using_ranges (gimple stmt)
7301e4b17023SJohn Marino {
7302e4b17023SJohn Marino   tree innerop, middleop, finaltype;
7303e4b17023SJohn Marino   gimple def_stmt;
7304e4b17023SJohn Marino   value_range_t *innervr;
7305e4b17023SJohn Marino   bool inner_unsigned_p, middle_unsigned_p, final_unsigned_p;
7306e4b17023SJohn Marino   unsigned inner_prec, middle_prec, final_prec;
7307e4b17023SJohn Marino   double_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
7308e4b17023SJohn Marino 
7309e4b17023SJohn Marino   finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
7310e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (finaltype))
7311e4b17023SJohn Marino     return false;
7312e4b17023SJohn Marino   middleop = gimple_assign_rhs1 (stmt);
7313e4b17023SJohn Marino   def_stmt = SSA_NAME_DEF_STMT (middleop);
7314e4b17023SJohn Marino   if (!is_gimple_assign (def_stmt)
7315e4b17023SJohn Marino       || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
7316e4b17023SJohn Marino     return false;
7317e4b17023SJohn Marino   innerop = gimple_assign_rhs1 (def_stmt);
7318e4b17023SJohn Marino   if (TREE_CODE (innerop) != SSA_NAME)
7319e4b17023SJohn Marino     return false;
7320e4b17023SJohn Marino 
7321e4b17023SJohn Marino   /* Get the value-range of the inner operand.  */
7322e4b17023SJohn Marino   innervr = get_value_range (innerop);
7323e4b17023SJohn Marino   if (innervr->type != VR_RANGE
7324e4b17023SJohn Marino       || TREE_CODE (innervr->min) != INTEGER_CST
7325e4b17023SJohn Marino       || TREE_CODE (innervr->max) != INTEGER_CST)
7326e4b17023SJohn Marino     return false;
7327e4b17023SJohn Marino 
7328e4b17023SJohn Marino   /* Simulate the conversion chain to check if the result is equal if
7329e4b17023SJohn Marino      the middle conversion is removed.  */
7330e4b17023SJohn Marino   innermin = tree_to_double_int (innervr->min);
7331e4b17023SJohn Marino   innermax = tree_to_double_int (innervr->max);
7332e4b17023SJohn Marino 
7333e4b17023SJohn Marino   inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
7334e4b17023SJohn Marino   middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
7335e4b17023SJohn Marino   final_prec = TYPE_PRECISION (finaltype);
7336e4b17023SJohn Marino 
7337e4b17023SJohn Marino   /* If the first conversion is not injective, the second must not
7338e4b17023SJohn Marino      be widening.  */
7339e4b17023SJohn Marino   if (double_int_cmp (double_int_sub (innermax, innermin),
7340e4b17023SJohn Marino 		      double_int_mask (middle_prec), true) > 0
7341e4b17023SJohn Marino       && middle_prec < final_prec)
7342e4b17023SJohn Marino     return false;
7343e4b17023SJohn Marino   /* We also want a medium value so that we can track the effect that
7344e4b17023SJohn Marino      narrowing conversions with sign change have.  */
7345e4b17023SJohn Marino   inner_unsigned_p = TYPE_UNSIGNED (TREE_TYPE (innerop));
7346e4b17023SJohn Marino   if (inner_unsigned_p)
7347e4b17023SJohn Marino     innermed = double_int_rshift (double_int_mask (inner_prec),
7348e4b17023SJohn Marino 				  1, inner_prec, false);
7349e4b17023SJohn Marino   else
7350e4b17023SJohn Marino     innermed = double_int_zero;
7351e4b17023SJohn Marino   if (double_int_cmp (innermin, innermed, inner_unsigned_p) >= 0
7352e4b17023SJohn Marino       || double_int_cmp (innermed, innermax, inner_unsigned_p) >= 0)
7353e4b17023SJohn Marino     innermed = innermin;
7354e4b17023SJohn Marino 
7355e4b17023SJohn Marino   middle_unsigned_p = TYPE_UNSIGNED (TREE_TYPE (middleop));
7356e4b17023SJohn Marino   middlemin = double_int_ext (innermin, middle_prec, middle_unsigned_p);
7357e4b17023SJohn Marino   middlemed = double_int_ext (innermed, middle_prec, middle_unsigned_p);
7358e4b17023SJohn Marino   middlemax = double_int_ext (innermax, middle_prec, middle_unsigned_p);
7359e4b17023SJohn Marino 
7360e4b17023SJohn Marino   /* Require that the final conversion applied to both the original
7361e4b17023SJohn Marino      and the intermediate range produces the same result.  */
7362e4b17023SJohn Marino   final_unsigned_p = TYPE_UNSIGNED (finaltype);
7363e4b17023SJohn Marino   if (!double_int_equal_p (double_int_ext (middlemin,
7364e4b17023SJohn Marino 					   final_prec, final_unsigned_p),
7365e4b17023SJohn Marino 			   double_int_ext (innermin,
7366e4b17023SJohn Marino 					   final_prec, final_unsigned_p))
7367e4b17023SJohn Marino       || !double_int_equal_p (double_int_ext (middlemed,
7368e4b17023SJohn Marino 					      final_prec, final_unsigned_p),
7369e4b17023SJohn Marino 			      double_int_ext (innermed,
7370e4b17023SJohn Marino 					      final_prec, final_unsigned_p))
7371e4b17023SJohn Marino       || !double_int_equal_p (double_int_ext (middlemax,
7372e4b17023SJohn Marino 					      final_prec, final_unsigned_p),
7373e4b17023SJohn Marino 			      double_int_ext (innermax,
7374e4b17023SJohn Marino 					      final_prec, final_unsigned_p)))
7375e4b17023SJohn Marino     return false;
7376e4b17023SJohn Marino 
7377e4b17023SJohn Marino   gimple_assign_set_rhs1 (stmt, innerop);
7378e4b17023SJohn Marino   update_stmt (stmt);
7379e4b17023SJohn Marino   return true;
7380e4b17023SJohn Marino }
7381e4b17023SJohn Marino 
7382e4b17023SJohn Marino /* Return whether the value range *VR fits in an integer type specified
7383e4b17023SJohn Marino    by PRECISION and UNSIGNED_P.  */
7384e4b17023SJohn Marino 
7385e4b17023SJohn Marino static bool
range_fits_type_p(value_range_t * vr,unsigned precision,bool unsigned_p)7386e4b17023SJohn Marino range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
7387e4b17023SJohn Marino {
7388e4b17023SJohn Marino   tree src_type;
7389e4b17023SJohn Marino   unsigned src_precision;
7390e4b17023SJohn Marino   double_int tem;
7391e4b17023SJohn Marino 
7392e4b17023SJohn Marino   /* We can only handle integral and pointer types.  */
7393e4b17023SJohn Marino   src_type = TREE_TYPE (vr->min);
7394e4b17023SJohn Marino   if (!INTEGRAL_TYPE_P (src_type)
7395e4b17023SJohn Marino       && !POINTER_TYPE_P (src_type))
7396e4b17023SJohn Marino     return false;
7397e4b17023SJohn Marino 
7398e4b17023SJohn Marino   /* An extension is always fine, so is an identity transform.  */
7399e4b17023SJohn Marino   src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
7400e4b17023SJohn Marino   if (src_precision < precision
7401e4b17023SJohn Marino       || (src_precision == precision
7402e4b17023SJohn Marino 	  && TYPE_UNSIGNED (src_type) == unsigned_p))
7403e4b17023SJohn Marino     return true;
7404e4b17023SJohn Marino 
7405e4b17023SJohn Marino   /* Now we can only handle ranges with constant bounds.  */
7406e4b17023SJohn Marino   if (vr->type != VR_RANGE
7407e4b17023SJohn Marino       || TREE_CODE (vr->min) != INTEGER_CST
7408e4b17023SJohn Marino       || TREE_CODE (vr->max) != INTEGER_CST)
7409e4b17023SJohn Marino     return false;
7410e4b17023SJohn Marino 
7411e4b17023SJohn Marino   /* For precision-preserving sign-changes the MSB of the double-int
7412e4b17023SJohn Marino      has to be clear.  */
7413e4b17023SJohn Marino   if (src_precision == precision
7414e4b17023SJohn Marino       && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
7415e4b17023SJohn Marino     return false;
7416e4b17023SJohn Marino 
7417e4b17023SJohn Marino   /* Then we can perform the conversion on both ends and compare
7418e4b17023SJohn Marino      the result for equality.  */
7419e4b17023SJohn Marino   tem = double_int_ext (tree_to_double_int (vr->min), precision, unsigned_p);
7420e4b17023SJohn Marino   if (!double_int_equal_p (tree_to_double_int (vr->min), tem))
7421e4b17023SJohn Marino     return false;
7422e4b17023SJohn Marino   tem = double_int_ext (tree_to_double_int (vr->max), precision, unsigned_p);
7423e4b17023SJohn Marino   if (!double_int_equal_p (tree_to_double_int (vr->max), tem))
7424e4b17023SJohn Marino     return false;
7425e4b17023SJohn Marino 
7426e4b17023SJohn Marino   return true;
7427e4b17023SJohn Marino }
7428e4b17023SJohn Marino 
7429e4b17023SJohn Marino /* Simplify a conversion from integral SSA name to float in STMT.  */
7430e4b17023SJohn Marino 
7431e4b17023SJohn Marino static bool
simplify_float_conversion_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)7432e4b17023SJohn Marino simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
7433e4b17023SJohn Marino {
7434e4b17023SJohn Marino   tree rhs1 = gimple_assign_rhs1 (stmt);
7435e4b17023SJohn Marino   value_range_t *vr = get_value_range (rhs1);
7436e4b17023SJohn Marino   enum machine_mode fltmode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
7437e4b17023SJohn Marino   enum machine_mode mode;
7438e4b17023SJohn Marino   tree tem;
7439e4b17023SJohn Marino   gimple conv;
7440e4b17023SJohn Marino 
7441e4b17023SJohn Marino   /* We can only handle constant ranges.  */
7442e4b17023SJohn Marino   if (vr->type != VR_RANGE
7443e4b17023SJohn Marino       || TREE_CODE (vr->min) != INTEGER_CST
7444e4b17023SJohn Marino       || TREE_CODE (vr->max) != INTEGER_CST)
7445e4b17023SJohn Marino     return false;
7446e4b17023SJohn Marino 
7447e4b17023SJohn Marino   /* First check if we can use a signed type in place of an unsigned.  */
7448e4b17023SJohn Marino   if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
7449e4b17023SJohn Marino       && (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)), 0)
7450e4b17023SJohn Marino 	  != CODE_FOR_nothing)
7451e4b17023SJohn Marino       && range_fits_type_p (vr, GET_MODE_PRECISION
7452e4b17023SJohn Marino 			          (TYPE_MODE (TREE_TYPE (rhs1))), 0))
7453e4b17023SJohn Marino     mode = TYPE_MODE (TREE_TYPE (rhs1));
7454e4b17023SJohn Marino   /* If we can do the conversion in the current input mode do nothing.  */
7455e4b17023SJohn Marino   else if (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)),
7456e4b17023SJohn Marino 			TYPE_UNSIGNED (TREE_TYPE (rhs1))))
7457e4b17023SJohn Marino     return false;
7458e4b17023SJohn Marino   /* Otherwise search for a mode we can use, starting from the narrowest
7459e4b17023SJohn Marino      integer mode available.  */
7460e4b17023SJohn Marino   else
7461e4b17023SJohn Marino     {
7462e4b17023SJohn Marino       mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
7463e4b17023SJohn Marino       do
7464e4b17023SJohn Marino 	{
7465e4b17023SJohn Marino 	  /* If we cannot do a signed conversion to float from mode
7466e4b17023SJohn Marino 	     or if the value-range does not fit in the signed type
7467e4b17023SJohn Marino 	     try with a wider mode.  */
7468e4b17023SJohn Marino 	  if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
7469e4b17023SJohn Marino 	      && range_fits_type_p (vr, GET_MODE_PRECISION (mode), 0))
7470e4b17023SJohn Marino 	    break;
7471e4b17023SJohn Marino 
7472e4b17023SJohn Marino 	  mode = GET_MODE_WIDER_MODE (mode);
7473e4b17023SJohn Marino 	  /* But do not widen the input.  Instead leave that to the
7474e4b17023SJohn Marino 	     optabs expansion code.  */
7475e4b17023SJohn Marino 	  if (GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
7476e4b17023SJohn Marino 	    return false;
7477e4b17023SJohn Marino 	}
7478e4b17023SJohn Marino       while (mode != VOIDmode);
7479e4b17023SJohn Marino       if (mode == VOIDmode)
7480e4b17023SJohn Marino 	return false;
7481e4b17023SJohn Marino     }
7482e4b17023SJohn Marino 
7483e4b17023SJohn Marino   /* It works, insert a truncation or sign-change before the
7484e4b17023SJohn Marino      float conversion.  */
7485e4b17023SJohn Marino   tem = create_tmp_var (build_nonstandard_integer_type
7486e4b17023SJohn Marino 			  (GET_MODE_PRECISION (mode), 0), NULL);
7487e4b17023SJohn Marino   conv = gimple_build_assign_with_ops (NOP_EXPR, tem, rhs1, NULL_TREE);
7488e4b17023SJohn Marino   tem = make_ssa_name (tem, conv);
7489e4b17023SJohn Marino   gimple_assign_set_lhs (conv, tem);
7490e4b17023SJohn Marino   gsi_insert_before (gsi, conv, GSI_SAME_STMT);
7491e4b17023SJohn Marino   gimple_assign_set_rhs1 (stmt, tem);
7492e4b17023SJohn Marino   update_stmt (stmt);
7493e4b17023SJohn Marino 
7494e4b17023SJohn Marino   return true;
7495e4b17023SJohn Marino }
7496e4b17023SJohn Marino 
7497e4b17023SJohn Marino /* Simplify STMT using ranges if possible.  */
7498e4b17023SJohn Marino 
7499e4b17023SJohn Marino static bool
simplify_stmt_using_ranges(gimple_stmt_iterator * gsi)7500e4b17023SJohn Marino simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
7501e4b17023SJohn Marino {
7502e4b17023SJohn Marino   gimple stmt = gsi_stmt (*gsi);
7503e4b17023SJohn Marino   if (is_gimple_assign (stmt))
7504e4b17023SJohn Marino     {
7505e4b17023SJohn Marino       enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
7506e4b17023SJohn Marino       tree rhs1 = gimple_assign_rhs1 (stmt);
7507e4b17023SJohn Marino 
7508e4b17023SJohn Marino       switch (rhs_code)
7509e4b17023SJohn Marino 	{
7510e4b17023SJohn Marino 	case EQ_EXPR:
7511e4b17023SJohn Marino 	case NE_EXPR:
7512e4b17023SJohn Marino           /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
7513e4b17023SJohn Marino 	     if the RHS is zero or one, and the LHS are known to be boolean
7514e4b17023SJohn Marino 	     values.  */
7515e4b17023SJohn Marino 	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7516e4b17023SJohn Marino 	    return simplify_truth_ops_using_ranges (gsi, stmt);
7517e4b17023SJohn Marino 	  break;
7518e4b17023SJohn Marino 
7519e4b17023SJohn Marino       /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
7520e4b17023SJohn Marino 	 and BIT_AND_EXPR respectively if the first operand is greater
7521e4b17023SJohn Marino 	 than zero and the second operand is an exact power of two.  */
7522e4b17023SJohn Marino 	case TRUNC_DIV_EXPR:
7523e4b17023SJohn Marino 	case TRUNC_MOD_EXPR:
7524e4b17023SJohn Marino 	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
7525e4b17023SJohn Marino 	      && integer_pow2p (gimple_assign_rhs2 (stmt)))
7526e4b17023SJohn Marino 	    return simplify_div_or_mod_using_ranges (stmt);
7527e4b17023SJohn Marino 	  break;
7528e4b17023SJohn Marino 
7529e4b17023SJohn Marino       /* Transform ABS (X) into X or -X as appropriate.  */
7530e4b17023SJohn Marino 	case ABS_EXPR:
7531e4b17023SJohn Marino 	  if (TREE_CODE (rhs1) == SSA_NAME
7532e4b17023SJohn Marino 	      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7533e4b17023SJohn Marino 	    return simplify_abs_using_ranges (stmt);
7534e4b17023SJohn Marino 	  break;
7535e4b17023SJohn Marino 
7536e4b17023SJohn Marino 	case BIT_AND_EXPR:
7537e4b17023SJohn Marino 	case BIT_IOR_EXPR:
7538e4b17023SJohn Marino 	  /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
7539e4b17023SJohn Marino 	     if all the bits being cleared are already cleared or
7540e4b17023SJohn Marino 	     all the bits being set are already set.  */
7541e4b17023SJohn Marino 	  if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7542e4b17023SJohn Marino 	    return simplify_bit_ops_using_ranges (gsi, stmt);
7543e4b17023SJohn Marino 	  break;
7544e4b17023SJohn Marino 
7545e4b17023SJohn Marino 	CASE_CONVERT:
7546e4b17023SJohn Marino 	  if (TREE_CODE (rhs1) == SSA_NAME
7547e4b17023SJohn Marino 	      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7548e4b17023SJohn Marino 	    return simplify_conversion_using_ranges (stmt);
7549e4b17023SJohn Marino 	  break;
7550e4b17023SJohn Marino 
7551e4b17023SJohn Marino 	case FLOAT_EXPR:
7552e4b17023SJohn Marino 	  if (TREE_CODE (rhs1) == SSA_NAME
7553e4b17023SJohn Marino 	      && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7554e4b17023SJohn Marino 	    return simplify_float_conversion_using_ranges (gsi, stmt);
7555e4b17023SJohn Marino 	  break;
7556e4b17023SJohn Marino 
7557e4b17023SJohn Marino 	default:
7558e4b17023SJohn Marino 	  break;
7559e4b17023SJohn Marino 	}
7560e4b17023SJohn Marino     }
7561e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_COND)
7562e4b17023SJohn Marino     return simplify_cond_using_ranges (stmt);
7563e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_SWITCH)
7564e4b17023SJohn Marino     return simplify_switch_using_ranges (stmt);
7565e4b17023SJohn Marino 
7566e4b17023SJohn Marino   return false;
7567e4b17023SJohn Marino }
7568e4b17023SJohn Marino 
7569e4b17023SJohn Marino /* If the statement pointed by SI has a predicate whose value can be
7570e4b17023SJohn Marino    computed using the value range information computed by VRP, compute
7571e4b17023SJohn Marino    its value and return true.  Otherwise, return false.  */
7572e4b17023SJohn Marino 
7573e4b17023SJohn Marino static bool
fold_predicate_in(gimple_stmt_iterator * si)7574e4b17023SJohn Marino fold_predicate_in (gimple_stmt_iterator *si)
7575e4b17023SJohn Marino {
7576e4b17023SJohn Marino   bool assignment_p = false;
7577e4b17023SJohn Marino   tree val;
7578e4b17023SJohn Marino   gimple stmt = gsi_stmt (*si);
7579e4b17023SJohn Marino 
7580e4b17023SJohn Marino   if (is_gimple_assign (stmt)
7581e4b17023SJohn Marino       && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
7582e4b17023SJohn Marino     {
7583e4b17023SJohn Marino       assignment_p = true;
7584e4b17023SJohn Marino       val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
7585e4b17023SJohn Marino 				      gimple_assign_rhs1 (stmt),
7586e4b17023SJohn Marino 				      gimple_assign_rhs2 (stmt),
7587e4b17023SJohn Marino 				      stmt);
7588e4b17023SJohn Marino     }
7589e4b17023SJohn Marino   else if (gimple_code (stmt) == GIMPLE_COND)
7590e4b17023SJohn Marino     val = vrp_evaluate_conditional (gimple_cond_code (stmt),
7591e4b17023SJohn Marino 				    gimple_cond_lhs (stmt),
7592e4b17023SJohn Marino 				    gimple_cond_rhs (stmt),
7593e4b17023SJohn Marino 				    stmt);
7594e4b17023SJohn Marino   else
7595e4b17023SJohn Marino     return false;
7596e4b17023SJohn Marino 
7597e4b17023SJohn Marino   if (val)
7598e4b17023SJohn Marino     {
7599e4b17023SJohn Marino       if (assignment_p)
7600e4b17023SJohn Marino         val = fold_convert (gimple_expr_type (stmt), val);
7601e4b17023SJohn Marino 
7602e4b17023SJohn Marino       if (dump_file)
7603e4b17023SJohn Marino 	{
7604e4b17023SJohn Marino 	  fprintf (dump_file, "Folding predicate ");
7605e4b17023SJohn Marino 	  print_gimple_expr (dump_file, stmt, 0, 0);
7606e4b17023SJohn Marino 	  fprintf (dump_file, " to ");
7607e4b17023SJohn Marino 	  print_generic_expr (dump_file, val, 0);
7608e4b17023SJohn Marino 	  fprintf (dump_file, "\n");
7609e4b17023SJohn Marino 	}
7610e4b17023SJohn Marino 
7611e4b17023SJohn Marino       if (is_gimple_assign (stmt))
7612e4b17023SJohn Marino 	gimple_assign_set_rhs_from_tree (si, val);
7613e4b17023SJohn Marino       else
7614e4b17023SJohn Marino 	{
7615e4b17023SJohn Marino 	  gcc_assert (gimple_code (stmt) == GIMPLE_COND);
7616e4b17023SJohn Marino 	  if (integer_zerop (val))
7617e4b17023SJohn Marino 	    gimple_cond_make_false (stmt);
7618e4b17023SJohn Marino 	  else if (integer_onep (val))
7619e4b17023SJohn Marino 	    gimple_cond_make_true (stmt);
7620e4b17023SJohn Marino 	  else
7621e4b17023SJohn Marino 	    gcc_unreachable ();
7622e4b17023SJohn Marino 	}
7623e4b17023SJohn Marino 
7624e4b17023SJohn Marino       return true;
7625e4b17023SJohn Marino     }
7626e4b17023SJohn Marino 
7627e4b17023SJohn Marino   return false;
7628e4b17023SJohn Marino }
7629e4b17023SJohn Marino 
7630e4b17023SJohn Marino /* Callback for substitute_and_fold folding the stmt at *SI.  */
7631e4b17023SJohn Marino 
7632e4b17023SJohn Marino static bool
vrp_fold_stmt(gimple_stmt_iterator * si)7633e4b17023SJohn Marino vrp_fold_stmt (gimple_stmt_iterator *si)
7634e4b17023SJohn Marino {
7635e4b17023SJohn Marino   if (fold_predicate_in (si))
7636e4b17023SJohn Marino     return true;
7637e4b17023SJohn Marino 
7638e4b17023SJohn Marino   return simplify_stmt_using_ranges (si);
7639e4b17023SJohn Marino }
7640e4b17023SJohn Marino 
7641e4b17023SJohn Marino /* Stack of dest,src equivalency pairs that need to be restored after
7642e4b17023SJohn Marino    each attempt to thread a block's incoming edge to an outgoing edge.
7643e4b17023SJohn Marino 
7644e4b17023SJohn Marino    A NULL entry is used to mark the end of pairs which need to be
7645e4b17023SJohn Marino    restored.  */
VEC(tree,heap)7646e4b17023SJohn Marino static VEC(tree,heap) *stack;
7647e4b17023SJohn Marino 
7648e4b17023SJohn Marino /* A trivial wrapper so that we can present the generic jump threading
7649e4b17023SJohn Marino    code with a simple API for simplifying statements.  STMT is the
7650e4b17023SJohn Marino    statement we want to simplify, WITHIN_STMT provides the location
7651e4b17023SJohn Marino    for any overflow warnings.  */
7652e4b17023SJohn Marino 
7653e4b17023SJohn Marino static tree
7654e4b17023SJohn Marino simplify_stmt_for_jump_threading (gimple stmt, gimple within_stmt)
7655e4b17023SJohn Marino {
7656e4b17023SJohn Marino   /* We only use VRP information to simplify conditionals.  This is
7657e4b17023SJohn Marino      overly conservative, but it's unclear if doing more would be
7658e4b17023SJohn Marino      worth the compile time cost.  */
7659e4b17023SJohn Marino   if (gimple_code (stmt) != GIMPLE_COND)
7660e4b17023SJohn Marino     return NULL;
7661e4b17023SJohn Marino 
7662e4b17023SJohn Marino   return vrp_evaluate_conditional (gimple_cond_code (stmt),
7663e4b17023SJohn Marino 				   gimple_cond_lhs (stmt),
7664e4b17023SJohn Marino 				   gimple_cond_rhs (stmt), within_stmt);
7665e4b17023SJohn Marino }
7666e4b17023SJohn Marino 
7667e4b17023SJohn Marino /* Blocks which have more than one predecessor and more than
7668e4b17023SJohn Marino    one successor present jump threading opportunities, i.e.,
7669e4b17023SJohn Marino    when the block is reached from a specific predecessor, we
7670e4b17023SJohn Marino    may be able to determine which of the outgoing edges will
7671e4b17023SJohn Marino    be traversed.  When this optimization applies, we are able
7672e4b17023SJohn Marino    to avoid conditionals at runtime and we may expose secondary
7673e4b17023SJohn Marino    optimization opportunities.
7674e4b17023SJohn Marino 
7675e4b17023SJohn Marino    This routine is effectively a driver for the generic jump
7676e4b17023SJohn Marino    threading code.  It basically just presents the generic code
7677e4b17023SJohn Marino    with edges that may be suitable for jump threading.
7678e4b17023SJohn Marino 
7679e4b17023SJohn Marino    Unlike DOM, we do not iterate VRP if jump threading was successful.
7680e4b17023SJohn Marino    While iterating may expose new opportunities for VRP, it is expected
7681e4b17023SJohn Marino    those opportunities would be very limited and the compile time cost
7682e4b17023SJohn Marino    to expose those opportunities would be significant.
7683e4b17023SJohn Marino 
7684e4b17023SJohn Marino    As jump threading opportunities are discovered, they are registered
7685e4b17023SJohn Marino    for later realization.  */
7686e4b17023SJohn Marino 
7687e4b17023SJohn Marino static void
identify_jump_threads(void)7688e4b17023SJohn Marino identify_jump_threads (void)
7689e4b17023SJohn Marino {
7690e4b17023SJohn Marino   basic_block bb;
7691e4b17023SJohn Marino   gimple dummy;
7692e4b17023SJohn Marino   int i;
7693e4b17023SJohn Marino   edge e;
7694e4b17023SJohn Marino 
7695e4b17023SJohn Marino   /* Ugh.  When substituting values earlier in this pass we can
7696e4b17023SJohn Marino      wipe the dominance information.  So rebuild the dominator
7697e4b17023SJohn Marino      information as we need it within the jump threading code.  */
7698e4b17023SJohn Marino   calculate_dominance_info (CDI_DOMINATORS);
7699e4b17023SJohn Marino 
7700e4b17023SJohn Marino   /* We do not allow VRP information to be used for jump threading
7701e4b17023SJohn Marino      across a back edge in the CFG.  Otherwise it becomes too
7702e4b17023SJohn Marino      difficult to avoid eliminating loop exit tests.  Of course
7703e4b17023SJohn Marino      EDGE_DFS_BACK is not accurate at this time so we have to
7704e4b17023SJohn Marino      recompute it.  */
7705e4b17023SJohn Marino   mark_dfs_back_edges ();
7706e4b17023SJohn Marino 
7707e4b17023SJohn Marino   /* Do not thread across edges we are about to remove.  Just marking
7708e4b17023SJohn Marino      them as EDGE_DFS_BACK will do.  */
7709e4b17023SJohn Marino   FOR_EACH_VEC_ELT (edge, to_remove_edges, i, e)
7710e4b17023SJohn Marino     e->flags |= EDGE_DFS_BACK;
7711e4b17023SJohn Marino 
7712e4b17023SJohn Marino   /* Allocate our unwinder stack to unwind any temporary equivalences
7713e4b17023SJohn Marino      that might be recorded.  */
7714e4b17023SJohn Marino   stack = VEC_alloc (tree, heap, 20);
7715e4b17023SJohn Marino 
7716e4b17023SJohn Marino   /* To avoid lots of silly node creation, we create a single
7717e4b17023SJohn Marino      conditional and just modify it in-place when attempting to
7718e4b17023SJohn Marino      thread jumps.  */
7719e4b17023SJohn Marino   dummy = gimple_build_cond (EQ_EXPR,
7720e4b17023SJohn Marino 			     integer_zero_node, integer_zero_node,
7721e4b17023SJohn Marino 			     NULL, NULL);
7722e4b17023SJohn Marino 
7723e4b17023SJohn Marino   /* Walk through all the blocks finding those which present a
7724e4b17023SJohn Marino      potential jump threading opportunity.  We could set this up
7725e4b17023SJohn Marino      as a dominator walker and record data during the walk, but
7726e4b17023SJohn Marino      I doubt it's worth the effort for the classes of jump
7727e4b17023SJohn Marino      threading opportunities we are trying to identify at this
7728e4b17023SJohn Marino      point in compilation.  */
7729e4b17023SJohn Marino   FOR_EACH_BB (bb)
7730e4b17023SJohn Marino     {
7731e4b17023SJohn Marino       gimple last;
7732e4b17023SJohn Marino 
7733e4b17023SJohn Marino       /* If the generic jump threading code does not find this block
7734e4b17023SJohn Marino 	 interesting, then there is nothing to do.  */
7735e4b17023SJohn Marino       if (! potentially_threadable_block (bb))
7736e4b17023SJohn Marino 	continue;
7737e4b17023SJohn Marino 
7738e4b17023SJohn Marino       /* We only care about blocks ending in a COND_EXPR.  While there
7739e4b17023SJohn Marino 	 may be some value in handling SWITCH_EXPR here, I doubt it's
7740e4b17023SJohn Marino 	 terribly important.  */
7741e4b17023SJohn Marino       last = gsi_stmt (gsi_last_bb (bb));
7742e4b17023SJohn Marino 
7743e4b17023SJohn Marino       /* We're basically looking for a switch or any kind of conditional with
7744e4b17023SJohn Marino 	 integral or pointer type arguments.  Note the type of the second
7745e4b17023SJohn Marino 	 argument will be the same as the first argument, so no need to
7746e4b17023SJohn Marino 	 check it explicitly.  */
7747e4b17023SJohn Marino       if (gimple_code (last) == GIMPLE_SWITCH
7748e4b17023SJohn Marino 	  || (gimple_code (last) == GIMPLE_COND
7749e4b17023SJohn Marino       	      && TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
7750e4b17023SJohn Marino 	      && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
7751e4b17023SJohn Marino 		  || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (last))))
7752e4b17023SJohn Marino 	      && (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
7753e4b17023SJohn Marino 		  || is_gimple_min_invariant (gimple_cond_rhs (last)))))
7754e4b17023SJohn Marino 	{
7755e4b17023SJohn Marino 	  edge_iterator ei;
7756e4b17023SJohn Marino 
7757e4b17023SJohn Marino 	  /* We've got a block with multiple predecessors and multiple
7758e4b17023SJohn Marino 	     successors which also ends in a suitable conditional or
7759e4b17023SJohn Marino 	     switch statement.  For each predecessor, see if we can thread
7760e4b17023SJohn Marino 	     it to a specific successor.  */
7761e4b17023SJohn Marino 	  FOR_EACH_EDGE (e, ei, bb->preds)
7762e4b17023SJohn Marino 	    {
7763e4b17023SJohn Marino 	      /* Do not thread across back edges or abnormal edges
7764e4b17023SJohn Marino 		 in the CFG.  */
7765e4b17023SJohn Marino 	      if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
7766e4b17023SJohn Marino 		continue;
7767e4b17023SJohn Marino 
7768e4b17023SJohn Marino 	      thread_across_edge (dummy, e, true, &stack,
7769e4b17023SJohn Marino 				  simplify_stmt_for_jump_threading);
7770e4b17023SJohn Marino 	    }
7771e4b17023SJohn Marino 	}
7772e4b17023SJohn Marino     }
7773e4b17023SJohn Marino 
7774e4b17023SJohn Marino   /* We do not actually update the CFG or SSA graphs at this point as
7775e4b17023SJohn Marino      ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet
7776e4b17023SJohn Marino      handle ASSERT_EXPRs gracefully.  */
7777e4b17023SJohn Marino }
7778e4b17023SJohn Marino 
7779e4b17023SJohn Marino /* We identified all the jump threading opportunities earlier, but could
7780e4b17023SJohn Marino    not transform the CFG at that time.  This routine transforms the
7781e4b17023SJohn Marino    CFG and arranges for the dominator tree to be rebuilt if necessary.
7782e4b17023SJohn Marino 
7783e4b17023SJohn Marino    Note the SSA graph update will occur during the normal TODO
7784e4b17023SJohn Marino    processing by the pass manager.  */
7785e4b17023SJohn Marino static void
finalize_jump_threads(void)7786e4b17023SJohn Marino finalize_jump_threads (void)
7787e4b17023SJohn Marino {
7788e4b17023SJohn Marino   thread_through_all_blocks (false);
7789e4b17023SJohn Marino   VEC_free (tree, heap, stack);
7790e4b17023SJohn Marino }
7791e4b17023SJohn Marino 
7792e4b17023SJohn Marino 
7793e4b17023SJohn Marino /* Traverse all the blocks folding conditionals with known ranges.  */
7794e4b17023SJohn Marino 
7795e4b17023SJohn Marino static void
vrp_finalize(void)7796e4b17023SJohn Marino vrp_finalize (void)
7797e4b17023SJohn Marino {
7798e4b17023SJohn Marino   size_t i;
7799e4b17023SJohn Marino 
7800e4b17023SJohn Marino   values_propagated = true;
7801e4b17023SJohn Marino 
7802e4b17023SJohn Marino   if (dump_file)
7803e4b17023SJohn Marino     {
7804e4b17023SJohn Marino       fprintf (dump_file, "\nValue ranges after VRP:\n\n");
7805e4b17023SJohn Marino       dump_all_value_ranges (dump_file);
7806e4b17023SJohn Marino       fprintf (dump_file, "\n");
7807e4b17023SJohn Marino     }
7808e4b17023SJohn Marino 
7809e4b17023SJohn Marino   substitute_and_fold (op_with_constant_singleton_value_range,
7810e4b17023SJohn Marino 		       vrp_fold_stmt, false);
7811e4b17023SJohn Marino 
7812e4b17023SJohn Marino   if (warn_array_bounds)
7813e4b17023SJohn Marino     check_all_array_refs ();
7814e4b17023SJohn Marino 
7815e4b17023SJohn Marino   /* We must identify jump threading opportunities before we release
7816e4b17023SJohn Marino      the datastructures built by VRP.  */
7817e4b17023SJohn Marino   identify_jump_threads ();
7818e4b17023SJohn Marino 
7819e4b17023SJohn Marino   /* Free allocated memory.  */
7820e4b17023SJohn Marino   for (i = 0; i < num_vr_values; i++)
7821e4b17023SJohn Marino     if (vr_value[i])
7822e4b17023SJohn Marino       {
7823e4b17023SJohn Marino 	BITMAP_FREE (vr_value[i]->equiv);
7824e4b17023SJohn Marino 	free (vr_value[i]);
7825e4b17023SJohn Marino       }
7826e4b17023SJohn Marino 
7827e4b17023SJohn Marino   free (vr_value);
7828e4b17023SJohn Marino   free (vr_phi_edge_counts);
7829e4b17023SJohn Marino 
7830e4b17023SJohn Marino   /* So that we can distinguish between VRP data being available
7831e4b17023SJohn Marino      and not available.  */
7832e4b17023SJohn Marino   vr_value = NULL;
7833e4b17023SJohn Marino   vr_phi_edge_counts = NULL;
7834e4b17023SJohn Marino }
7835e4b17023SJohn Marino 
7836e4b17023SJohn Marino 
7837e4b17023SJohn Marino /* Main entry point to VRP (Value Range Propagation).  This pass is
7838e4b17023SJohn Marino    loosely based on J. R. C. Patterson, ``Accurate Static Branch
7839e4b17023SJohn Marino    Prediction by Value Range Propagation,'' in SIGPLAN Conference on
7840e4b17023SJohn Marino    Programming Language Design and Implementation, pp. 67-78, 1995.
7841e4b17023SJohn Marino    Also available at http://citeseer.ist.psu.edu/patterson95accurate.html
7842e4b17023SJohn Marino 
7843e4b17023SJohn Marino    This is essentially an SSA-CCP pass modified to deal with ranges
7844e4b17023SJohn Marino    instead of constants.
7845e4b17023SJohn Marino 
7846e4b17023SJohn Marino    While propagating ranges, we may find that two or more SSA name
7847e4b17023SJohn Marino    have equivalent, though distinct ranges.  For instance,
7848e4b17023SJohn Marino 
7849e4b17023SJohn Marino      1	x_9 = p_3->a;
7850e4b17023SJohn Marino      2	p_4 = ASSERT_EXPR <p_3, p_3 != 0>
7851e4b17023SJohn Marino      3	if (p_4 == q_2)
7852e4b17023SJohn Marino      4	  p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
7853e4b17023SJohn Marino      5	endif
7854e4b17023SJohn Marino      6	if (q_2)
7855e4b17023SJohn Marino 
7856e4b17023SJohn Marino    In the code above, pointer p_5 has range [q_2, q_2], but from the
7857e4b17023SJohn Marino    code we can also determine that p_5 cannot be NULL and, if q_2 had
7858e4b17023SJohn Marino    a non-varying range, p_5's range should also be compatible with it.
7859e4b17023SJohn Marino 
7860e4b17023SJohn Marino    These equivalences are created by two expressions: ASSERT_EXPR and
7861e4b17023SJohn Marino    copy operations.  Since p_5 is an assertion on p_4, and p_4 was the
7862e4b17023SJohn Marino    result of another assertion, then we can use the fact that p_5 and
7863e4b17023SJohn Marino    p_4 are equivalent when evaluating p_5's range.
7864e4b17023SJohn Marino 
7865e4b17023SJohn Marino    Together with value ranges, we also propagate these equivalences
7866e4b17023SJohn Marino    between names so that we can take advantage of information from
7867e4b17023SJohn Marino    multiple ranges when doing final replacement.  Note that this
7868e4b17023SJohn Marino    equivalency relation is transitive but not symmetric.
7869e4b17023SJohn Marino 
7870e4b17023SJohn Marino    In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
7871e4b17023SJohn Marino    cannot assert that q_2 is equivalent to p_5 because q_2 may be used
7872e4b17023SJohn Marino    in contexts where that assertion does not hold (e.g., in line 6).
7873e4b17023SJohn Marino 
7874e4b17023SJohn Marino    TODO, the main difference between this pass and Patterson's is that
7875e4b17023SJohn Marino    we do not propagate edge probabilities.  We only compute whether
7876e4b17023SJohn Marino    edges can be taken or not.  That is, instead of having a spectrum
7877e4b17023SJohn Marino    of jump probabilities between 0 and 1, we only deal with 0, 1 and
7878e4b17023SJohn Marino    DON'T KNOW.  In the future, it may be worthwhile to propagate
7879e4b17023SJohn Marino    probabilities to aid branch prediction.  */
7880e4b17023SJohn Marino 
7881e4b17023SJohn Marino static unsigned int
execute_vrp(void)7882e4b17023SJohn Marino execute_vrp (void)
7883e4b17023SJohn Marino {
7884e4b17023SJohn Marino   int i;
7885e4b17023SJohn Marino   edge e;
7886e4b17023SJohn Marino   switch_update *su;
7887e4b17023SJohn Marino 
7888e4b17023SJohn Marino   loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
7889e4b17023SJohn Marino   rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
7890e4b17023SJohn Marino   scev_initialize ();
7891e4b17023SJohn Marino 
78925ce9237cSJohn Marino   /* ???  This ends up using stale EDGE_DFS_BACK for liveness computation.
78935ce9237cSJohn Marino      Inserting assertions may split edges which will invalidate
78945ce9237cSJohn Marino      EDGE_DFS_BACK.  */
7895e4b17023SJohn Marino   insert_range_assertions ();
7896e4b17023SJohn Marino 
7897e4b17023SJohn Marino   /* Estimate number of iterations - but do not use undefined behavior
7898e4b17023SJohn Marino      for this.  We can't do this lazily as other functions may compute
7899e4b17023SJohn Marino      this using undefined behavior.  */
7900e4b17023SJohn Marino   free_numbers_of_iterations_estimates ();
7901e4b17023SJohn Marino   estimate_numbers_of_iterations (false);
7902e4b17023SJohn Marino 
7903e4b17023SJohn Marino   to_remove_edges = VEC_alloc (edge, heap, 10);
7904e4b17023SJohn Marino   to_update_switch_stmts = VEC_alloc (switch_update, heap, 5);
7905e4b17023SJohn Marino   threadedge_initialize_values ();
7906e4b17023SJohn Marino 
79075ce9237cSJohn Marino   /* For visiting PHI nodes we need EDGE_DFS_BACK computed.  */
79085ce9237cSJohn Marino   mark_dfs_back_edges ();
79095ce9237cSJohn Marino 
7910e4b17023SJohn Marino   vrp_initialize ();
7911e4b17023SJohn Marino   ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
7912e4b17023SJohn Marino   vrp_finalize ();
7913e4b17023SJohn Marino 
7914e4b17023SJohn Marino   free_numbers_of_iterations_estimates ();
7915e4b17023SJohn Marino 
7916e4b17023SJohn Marino   /* ASSERT_EXPRs must be removed before finalizing jump threads
7917e4b17023SJohn Marino      as finalizing jump threads calls the CFG cleanup code which
7918e4b17023SJohn Marino      does not properly handle ASSERT_EXPRs.  */
7919e4b17023SJohn Marino   remove_range_assertions ();
7920e4b17023SJohn Marino 
7921e4b17023SJohn Marino   /* If we exposed any new variables, go ahead and put them into
7922e4b17023SJohn Marino      SSA form now, before we handle jump threading.  This simplifies
7923e4b17023SJohn Marino      interactions between rewriting of _DECL nodes into SSA form
7924e4b17023SJohn Marino      and rewriting SSA_NAME nodes into SSA form after block
7925e4b17023SJohn Marino      duplication and CFG manipulation.  */
7926e4b17023SJohn Marino   update_ssa (TODO_update_ssa);
7927e4b17023SJohn Marino 
7928e4b17023SJohn Marino   finalize_jump_threads ();
7929e4b17023SJohn Marino 
7930e4b17023SJohn Marino   /* Remove dead edges from SWITCH_EXPR optimization.  This leaves the
7931e4b17023SJohn Marino      CFG in a broken state and requires a cfg_cleanup run.  */
7932e4b17023SJohn Marino   FOR_EACH_VEC_ELT (edge, to_remove_edges, i, e)
7933e4b17023SJohn Marino     remove_edge (e);
7934e4b17023SJohn Marino   /* Update SWITCH_EXPR case label vector.  */
7935e4b17023SJohn Marino   FOR_EACH_VEC_ELT (switch_update, to_update_switch_stmts, i, su)
7936e4b17023SJohn Marino     {
7937e4b17023SJohn Marino       size_t j;
7938e4b17023SJohn Marino       size_t n = TREE_VEC_LENGTH (su->vec);
7939e4b17023SJohn Marino       tree label;
7940e4b17023SJohn Marino       gimple_switch_set_num_labels (su->stmt, n);
7941e4b17023SJohn Marino       for (j = 0; j < n; j++)
7942e4b17023SJohn Marino 	gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
7943e4b17023SJohn Marino       /* As we may have replaced the default label with a regular one
7944e4b17023SJohn Marino 	 make sure to make it a real default label again.  This ensures
7945e4b17023SJohn Marino 	 optimal expansion.  */
7946e4b17023SJohn Marino       label = gimple_switch_default_label (su->stmt);
7947e4b17023SJohn Marino       CASE_LOW (label) = NULL_TREE;
7948e4b17023SJohn Marino       CASE_HIGH (label) = NULL_TREE;
7949e4b17023SJohn Marino     }
7950e4b17023SJohn Marino 
7951e4b17023SJohn Marino   if (VEC_length (edge, to_remove_edges) > 0)
7952e4b17023SJohn Marino     free_dominance_info (CDI_DOMINATORS);
7953e4b17023SJohn Marino 
7954e4b17023SJohn Marino   VEC_free (edge, heap, to_remove_edges);
7955e4b17023SJohn Marino   VEC_free (switch_update, heap, to_update_switch_stmts);
7956e4b17023SJohn Marino   threadedge_finalize_values ();
7957e4b17023SJohn Marino 
7958e4b17023SJohn Marino   scev_finalize ();
7959e4b17023SJohn Marino   loop_optimizer_finalize ();
7960e4b17023SJohn Marino   return 0;
7961e4b17023SJohn Marino }
7962e4b17023SJohn Marino 
7963e4b17023SJohn Marino static bool
gate_vrp(void)7964e4b17023SJohn Marino gate_vrp (void)
7965e4b17023SJohn Marino {
7966e4b17023SJohn Marino   return flag_tree_vrp != 0;
7967e4b17023SJohn Marino }
7968e4b17023SJohn Marino 
7969e4b17023SJohn Marino struct gimple_opt_pass pass_vrp =
7970e4b17023SJohn Marino {
7971e4b17023SJohn Marino  {
7972e4b17023SJohn Marino   GIMPLE_PASS,
7973e4b17023SJohn Marino   "vrp",				/* name */
7974e4b17023SJohn Marino   gate_vrp,				/* gate */
7975e4b17023SJohn Marino   execute_vrp,				/* execute */
7976e4b17023SJohn Marino   NULL,					/* sub */
7977e4b17023SJohn Marino   NULL,					/* next */
7978e4b17023SJohn Marino   0,					/* static_pass_number */
7979e4b17023SJohn Marino   TV_TREE_VRP,				/* tv_id */
7980e4b17023SJohn Marino   PROP_ssa,				/* properties_required */
7981e4b17023SJohn Marino   0,					/* properties_provided */
7982e4b17023SJohn Marino   0,					/* properties_destroyed */
7983e4b17023SJohn Marino   0,					/* todo_flags_start */
7984e4b17023SJohn Marino   TODO_cleanup_cfg
7985e4b17023SJohn Marino     | TODO_update_ssa
7986e4b17023SJohn Marino     | TODO_verify_ssa
7987e4b17023SJohn Marino     | TODO_verify_flow
7988e4b17023SJohn Marino     | TODO_ggc_collect			/* todo_flags_finish */
7989e4b17023SJohn Marino  }
7990e4b17023SJohn Marino };
7991