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