@@ -28,6 +28,8 @@ const APInt &ConstantIntRanges::smin() const { return sminVal; }
28
28
29
29
const APInt &ConstantIntRanges::smax () const { return smaxVal; }
30
30
31
+ unsigned ConstantIntRanges::getBitWidth () const { return umin ().getBitWidth (); }
32
+
31
33
unsigned ConstantIntRanges::getStorageBitwidth (Type type) {
32
34
type = getElementTypeOrSelf (type);
33
35
if (type.isIndex ())
@@ -42,6 +44,16 @@ ConstantIntRanges ConstantIntRanges::maxRange(unsigned bitwidth) {
42
44
return fromUnsigned (APInt::getZero (bitwidth), APInt::getMaxValue (bitwidth));
43
45
}
44
46
47
+ ConstantIntRanges ConstantIntRanges::poison (unsigned bitwidth) {
48
+ if (bitwidth == 0 )
49
+ return maxRange (0 );
50
+
51
+ // Poison is represented by an empty range.
52
+ auto max = APInt::getZero (bitwidth);
53
+ auto min = max + 1 ;
54
+ return {min, max, min, max};
55
+ }
56
+
45
57
ConstantIntRanges ConstantIntRanges::constant (const APInt &value) {
46
58
return {value, value, value, value};
47
59
}
@@ -85,15 +97,37 @@ ConstantIntRanges
85
97
ConstantIntRanges::rangeUnion (const ConstantIntRanges &other) const {
86
98
// "Not an integer" poisons everything and also cannot be fed to comparison
87
99
// operators.
88
- if (umin (). getBitWidth () == 0 )
100
+ if (getBitWidth () == 0 )
89
101
return *this ;
90
- if (other.umin (). getBitWidth () == 0 )
102
+ if (other.getBitWidth () == 0 )
91
103
return other;
92
104
93
- const APInt &uminUnion = umin ().ult (other.umin ()) ? umin () : other.umin ();
94
- const APInt &umaxUnion = umax ().ugt (other.umax ()) ? umax () : other.umax ();
95
- const APInt &sminUnion = smin ().slt (other.smin ()) ? smin () : other.smin ();
96
- const APInt &smaxUnion = smax ().sgt (other.smax ()) ? smax () : other.smax ();
105
+ APInt uminUnion;
106
+ APInt umaxUnion;
107
+ APInt sminUnion;
108
+ APInt smaxUnion;
109
+
110
+ if (isUnsignedPoison ()) {
111
+ uminUnion = other.umin ();
112
+ umaxUnion = other.umax ();
113
+ } else if (other.isUnsignedPoison ()) {
114
+ uminUnion = umin ();
115
+ umaxUnion = umax ();
116
+ } else {
117
+ uminUnion = umin ().ult (other.umin ()) ? umin () : other.umin ();
118
+ umaxUnion = umax ().ugt (other.umax ()) ? umax () : other.umax ();
119
+ }
120
+
121
+ if (isSignedPoison ()) {
122
+ sminUnion = other.smin ();
123
+ smaxUnion = other.smax ();
124
+ } else if (other.isSignedPoison ()) {
125
+ sminUnion = smin ();
126
+ smaxUnion = smax ();
127
+ } else {
128
+ sminUnion = smin ().slt (other.smin ()) ? smin () : other.smin ();
129
+ smaxUnion = smax ().sgt (other.smax ()) ? smax () : other.smax ();
130
+ }
97
131
98
132
return {uminUnion, umaxUnion, sminUnion, smaxUnion};
99
133
}
@@ -102,15 +136,37 @@ ConstantIntRanges
102
136
ConstantIntRanges::intersection (const ConstantIntRanges &other) const {
103
137
// "Not an integer" poisons everything and also cannot be fed to comparison
104
138
// operators.
105
- if (umin (). getBitWidth () == 0 )
139
+ if (getBitWidth () == 0 )
106
140
return *this ;
107
- if (other.umin (). getBitWidth () == 0 )
141
+ if (other.getBitWidth () == 0 )
108
142
return other;
109
143
110
- const APInt &uminIntersect = umin ().ugt (other.umin ()) ? umin () : other.umin ();
111
- const APInt &umaxIntersect = umax ().ult (other.umax ()) ? umax () : other.umax ();
112
- const APInt &sminIntersect = smin ().sgt (other.smin ()) ? smin () : other.smin ();
113
- const APInt &smaxIntersect = smax ().slt (other.smax ()) ? smax () : other.smax ();
144
+ APInt uminIntersect;
145
+ APInt umaxIntersect;
146
+ APInt sminIntersect;
147
+ APInt smaxIntersect;
148
+
149
+ if (isUnsignedPoison ()) {
150
+ uminIntersect = umin ();
151
+ umaxIntersect = umax ();
152
+ } else if (other.isUnsignedPoison ()) {
153
+ uminIntersect = other.umin ();
154
+ umaxIntersect = other.umax ();
155
+ } else {
156
+ uminIntersect = umin ().ugt (other.umin ()) ? umin () : other.umin ();
157
+ umaxIntersect = umax ().ult (other.umax ()) ? umax () : other.umax ();
158
+ }
159
+
160
+ if (isSignedPoison ()) {
161
+ sminIntersect = smin ();
162
+ smaxIntersect = smax ();
163
+ } else if (other.isSignedPoison ()) {
164
+ sminIntersect = other.smin ();
165
+ smaxIntersect = other.smax ();
166
+ } else {
167
+ sminIntersect = smin ().sgt (other.smin ()) ? smin () : other.smin ();
168
+ smaxIntersect = smax ().slt (other.smax ()) ? smax () : other.smax ();
169
+ }
114
170
115
171
return {uminIntersect, umaxIntersect, sminIntersect, smaxIntersect};
116
172
}
@@ -124,6 +180,14 @@ std::optional<APInt> ConstantIntRanges::getConstantValue() const {
124
180
return std::nullopt;
125
181
}
126
182
183
+ bool ConstantIntRanges::isSignedPoison () const {
184
+ return getBitWidth () == 0 || smin ().sgt (smax ());
185
+ }
186
+
187
+ bool ConstantIntRanges::isUnsignedPoison () const {
188
+ return getBitWidth () == 0 || umin ().ugt (umax ());
189
+ }
190
+
127
191
raw_ostream &mlir::operator <<(raw_ostream &os, const ConstantIntRanges &range) {
128
192
os << " unsigned : [" ;
129
193
range.umin ().print (os, /* isSigned*/ false );
0 commit comments