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)
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
,
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
,
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
,
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
,
53 extern void wide_int_range_set_zero_nonzero_bits (signop
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
121 signop sign
, unsigned prec
,
122 const wide_int
÷nd_min
,
123 const wide_int
÷nd_max
,
124 const wide_int
&divisor_min
,
125 const wide_int
&divisor_max
,
126 bool overflow_undefined
,
129 wide_int
&extra_min
, wide_int
&extra_max
);
131 /* Return TRUE if shifting by range [MIN, MAX] is undefined behavior. */
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
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]. */
151 wide_int_range_min_max (wide_int
&min
, wide_int
&max
,
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
162 if (min
== wi::min_value (prec
, sign
)
163 && max
== wi::max_value (prec
, sign
))
168 /* Return TRUE if 0 is within [WMIN, WMAX]. */
171 wide_int_range_includes_zero_p (const wide_int
&wmin
, const wide_int
&wmax
,
174 return wi::le_p (wmin
, 0, sign
) && wi::ge_p (wmax
, 0, sign
);
177 /* Return TRUE if [WMIN, WMAX] is the singleton 0. */
180 wide_int_range_zero_p (const wide_int
&wmin
, const wide_int
&wmax
,
183 return wmin
== wmax
&& wi::eq_p (wmin
, wi::zero (prec
));
186 #endif /* GCC_WIDE_INT_RANGE_H */