annotate gcc/wide-int-range.h @ 144:8f4e72ab4e11

fix segmentation fault caused by nothing next cur_op to end
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 21:23:56 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
131
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
1 /* Support routines for range operations on wide ints.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
2 Copyright (C) 2018 Free Software Foundation, Inc.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
3
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
4 This file is part of GCC.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
5
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
7 it under the terms of the GNU General Public License as published by
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
8 the Free Software Foundation; either version 3, or (at your option)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
9 any later version.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
10
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
14 GNU General Public License for more details.
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
15
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
19
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
20 #ifndef GCC_WIDE_INT_RANGE_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
21 #define GCC_WIDE_INT_RANGE_H
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
22
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
23 extern bool wide_int_range_cross_product (wide_int &res_lb, wide_int &res_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
24 enum tree_code code, signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
25 const wide_int &, const wide_int &,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
26 const wide_int &, const wide_int &,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
27 bool overflow_undefined);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
28 extern bool wide_int_range_mult_wrapping (wide_int &res_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
29 wide_int &res_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
30 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
31 unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
32 const wide_int &min0_,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
33 const wide_int &max0_,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
34 const wide_int &min1_,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
35 const wide_int &max1_);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
36 extern bool wide_int_range_multiplicative_op (wide_int &res_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
37 wide_int &res_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
38 enum tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
39 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
40 unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
41 const wide_int &vr0_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
42 const wide_int &vr0_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
43 const wide_int &vr1_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
44 const wide_int &vr1_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
45 bool overflow_undefined);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
46 extern bool wide_int_range_lshift (wide_int &res_lb, wide_int &res_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
47 signop sign, unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
48 const wide_int &, const wide_int &,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
49 const wide_int &, const wide_int &,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
50 bool overflow_undefined);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
51 extern void wide_int_range_set_zero_nonzero_bits (signop,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
52 const wide_int &lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
53 const wide_int &ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
54 wide_int &may_be_nonzero,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
55 wide_int &must_be_nonzero);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
56 extern bool wide_int_range_optimize_bit_op (wide_int &res_lb, wide_int &res_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
57 enum tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
58 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
59 const wide_int &vr0_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
60 const wide_int &vr0_ub,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
61 const wide_int &vr1_lb,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
62 const wide_int &vr1_ub);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
63 extern bool wide_int_range_get_mask_and_bounds (wide_int &mask,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
64 wide_int &lower_bound,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
65 wide_int &upper_bound,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
66 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
67 const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
68 const wide_int &vr1_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
69 const wide_int &vr1_max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
70 extern bool wide_int_range_bit_xor (wide_int &wmin, wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
71 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
72 unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
73 const wide_int &must_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
74 const wide_int &may_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
75 const wide_int &must_be_nonzero1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
76 const wide_int &may_be_nonzero1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
77 extern bool wide_int_range_bit_ior (wide_int &wmin, wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
78 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
79 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
80 const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
81 const wide_int &vr1_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
82 const wide_int &vr1_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
83 const wide_int &must_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
84 const wide_int &may_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
85 const wide_int &must_be_nonzero1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
86 const wide_int &may_be_nonzero1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
87 extern bool wide_int_range_bit_and (wide_int &wmin, wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
88 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
89 unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
90 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
91 const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
92 const wide_int &vr1_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
93 const wide_int &vr1_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
94 const wide_int &must_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
95 const wide_int &may_be_nonzero0,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
96 const wide_int &must_be_nonzero1,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
97 const wide_int &may_be_nonzero1);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
98 extern void wide_int_range_trunc_mod (wide_int &wmin, wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
99 signop sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
100 unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
101 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
102 const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
103 const wide_int &vr1_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
104 const wide_int &vr1_max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
105 extern bool wide_int_range_abs (wide_int &min, wide_int &max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
106 signop sign, unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
107 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
108 const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
109 bool overflow_undefined);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
110 extern bool wide_int_range_convert (wide_int &min, wide_int &max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
111 signop inner_sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
112 unsigned inner_prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
113 signop outer_sign,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
114 unsigned outer_prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
115 const wide_int &vr0_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
116 const wide_int &vr0_max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
117 extern bool wide_int_range_div (wide_int &wmin, wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
118 enum tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
119 signop sign, unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
120 const wide_int &dividend_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
121 const wide_int &dividend_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
122 const wide_int &divisor_min,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
123 const wide_int &divisor_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
124 bool overflow_undefined,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
125 bool &extra_range_p,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
126 wide_int &extra_min, wide_int &extra_max);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
127
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
128 /* Return TRUE if shifting by range [MIN, MAX] is undefined behavior,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
129 interpreting MIN and MAX according to SIGN. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
130
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
131 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
132 wide_int_range_shift_undefined_p (signop sign, unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
133 const wide_int &min, const wide_int &max)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
134 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
135 /* ?? Note: The original comment said this only applied to
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
136 RSHIFT_EXPR, but it was being applied to both left and right
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
137 shifts. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
138
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
139 /* Shifting by any values outside [0..prec-1], gets undefined
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
140 behavior from the shift operation. We cannot even trust
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
141 SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
142 shifts, and the operation at the tree level may be widened. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
143 return wi::lt_p (min, 0, sign) || wi::ge_p (max, prec, sign);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
144 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
145
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
146 /* Calculate MIN/MAX_EXPR of two ranges and store the result in [MIN, MAX]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
147
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
148 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
149 wide_int_range_min_max (wide_int &min, wide_int &max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
150 tree_code code,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
151 signop sign, unsigned prec,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
152 const wide_int &vr0_min, const wide_int &vr0_max,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
153 const wide_int &vr1_min, const wide_int &vr1_max)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
154 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
155 wi::overflow_type overflow;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
156 wide_int_binop (min, code, vr0_min, vr1_min, sign, &overflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
157 wide_int_binop (max, code, vr0_max, vr1_max, sign, &overflow);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
158 /* If the new range covers the entire domain, that's really no range
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
159 at all. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
160 if (min == wi::min_value (prec, sign)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
161 && max == wi::max_value (prec, sign))
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
162 return false;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
163 return true;
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
164 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
165
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
166 /* Return TRUE if 0 is within [WMIN, WMAX]. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
167
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
168 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
169 wide_int_range_includes_zero_p (const wide_int &wmin, const wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
170 signop sign)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
171 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
172 return wi::le_p (wmin, 0, sign) && wi::ge_p (wmax, 0, sign);
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
173 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
174
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
175 /* Return TRUE if [WMIN, WMAX] is the singleton 0. */
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
176
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
177 inline bool
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
178 wide_int_range_zero_p (const wide_int &wmin, const wide_int &wmax,
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
179 unsigned prec)
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
180 {
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
181 return wmin == wmax && wi::eq_p (wmin, wi::zero (prec));
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
182 }
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
183
84e7813d76e9 gcc-8.2
mir3636
parents:
diff changeset
184 #endif /* GCC_WIDE_INT_RANGE_H */