@@ -42,6 +42,16 @@ ConstantIntRanges ConstantIntRanges::maxRange(unsigned bitwidth) {
42
42
return fromUnsigned (APInt::getZero (bitwidth), APInt::getMaxValue (bitwidth));
43
43
}
44
44
45
+ ConstantIntRanges ConstantIntRanges::poison (unsigned bitwidth) {
46
+ if (bitwidth == 0 )
47
+ return maxRange (0 );
48
+
49
+ // Poison is represented by an empty range.
50
+ auto max = APInt::getZero (bitwidth);
51
+ auto min = max + 1 ;
52
+ return {min, max, min, max};
53
+ }
54
+
45
55
ConstantIntRanges ConstantIntRanges::constant (const APInt &value) {
46
56
return {value, value, value, value};
47
57
}
@@ -90,10 +100,32 @@ ConstantIntRanges::rangeUnion(const ConstantIntRanges &other) const {
90
100
if (other.umin ().getBitWidth () == 0 )
91
101
return other;
92
102
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 ();
103
+ APInt uminUnion;
104
+ APInt umaxUnion;
105
+ APInt sminUnion;
106
+ APInt smaxUnion;
107
+
108
+ if (isUnsignedPoison ()) {
109
+ uminUnion = other.umin ();
110
+ umaxUnion = other.umax ();
111
+ } else if (other.isUnsignedPoison ()) {
112
+ uminUnion = umin ();
113
+ umaxUnion = umax ();
114
+ } else {
115
+ uminUnion = umin ().ult (other.umin ()) ? umin () : other.umin ();
116
+ umaxUnion = umax ().ugt (other.umax ()) ? umax () : other.umax ();
117
+ }
118
+
119
+ if (isSignedPoison ()) {
120
+ sminUnion = other.smin ();
121
+ smaxUnion = other.smax ();
122
+ } else if (other.isSignedPoison ()) {
123
+ sminUnion = smin ();
124
+ smaxUnion = smax ();
125
+ } else {
126
+ sminUnion = smin ().slt (other.smin ()) ? smin () : other.smin ();
127
+ smaxUnion = smax ().sgt (other.smax ()) ? smax () : other.smax ();
128
+ }
97
129
98
130
return {uminUnion, umaxUnion, sminUnion, smaxUnion};
99
131
}
@@ -107,10 +139,32 @@ ConstantIntRanges::intersection(const ConstantIntRanges &other) const {
107
139
if (other.umin ().getBitWidth () == 0 )
108
140
return other;
109
141
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 ();
142
+ APInt uminIntersect;
143
+ APInt umaxIntersect;
144
+ APInt sminIntersect;
145
+ APInt smaxIntersect;
146
+
147
+ if (isUnsignedPoison ()) {
148
+ uminIntersect = umin ();
149
+ umaxIntersect = umax ();
150
+ } else if (other.isUnsignedPoison ()) {
151
+ uminIntersect = other.umin ();
152
+ umaxIntersect = other.umax ();
153
+ } else {
154
+ uminIntersect = umin ().ugt (other.umin ()) ? umin () : other.umin ();
155
+ umaxIntersect = umax ().ult (other.umax ()) ? umax () : other.umax ();
156
+ }
157
+
158
+ if (isSignedPoison ()) {
159
+ sminIntersect = smin ();
160
+ smaxIntersect = smax ();
161
+ } else if (other.isSignedPoison ()) {
162
+ sminIntersect = other.smin ();
163
+ smaxIntersect = other.smax ();
164
+ } else {
165
+ sminIntersect = smin ().sgt (other.smin ()) ? smin () : other.smin ();
166
+ smaxIntersect = smax ().slt (other.smax ()) ? smax () : other.smax ();
167
+ }
114
168
115
169
return {uminIntersect, umaxIntersect, sminIntersect, smaxIntersect};
116
170
}
@@ -124,6 +178,10 @@ std::optional<APInt> ConstantIntRanges::getConstantValue() const {
124
178
return std::nullopt;
125
179
}
126
180
181
+ bool ConstantIntRanges::isSignedPoison () const { return smin ().sgt (smax ()); }
182
+
183
+ bool ConstantIntRanges::isUnsignedPoison () const { return umin ().ugt (umax ()); }
184
+
127
185
raw_ostream &mlir::operator <<(raw_ostream &os, const ConstantIntRanges &range) {
128
186
os << " unsigned : [" ;
129
187
range.umin ().print (os, /* isSigned*/ false );
0 commit comments