@@ -29,7 +29,12 @@ class ValueLatticeElement {
2929 // / producing instruction is dead. Caution: We use this as the starting
3030 // / state in our local meet rules. In this usage, it's taken to mean
3131 // / "nothing known yet".
32- undefined,
32+ unknown,
33+
34+ // / This Value is an UndefValue constant or produces undef. Undefined values
35+ // / can be merged with constants (or single element constant ranges),
36+ // / assuming all uses of the result will be replaced.
37+ undef,
3338
3439 // / This Value has a specific constant value. (For constant integers,
3540 // / constantrange is used instead. Integer typed constantexprs can appear
@@ -60,14 +65,15 @@ class ValueLatticeElement {
6065
6166public:
6267 // Const and Range are initialized on-demand.
63- ValueLatticeElement () : Tag(undefined ) {}
68+ ValueLatticeElement () : Tag(unknown ) {}
6469
6570 // / Custom destructor to ensure Range is properly destroyed, when the object
6671 // / is deallocated.
6772 ~ValueLatticeElement () {
6873 switch (Tag) {
6974 case overdefined:
70- case undefined:
75+ case unknown:
76+ case undef:
7177 case constant:
7278 case notconstant:
7379 break ;
@@ -79,7 +85,7 @@ class ValueLatticeElement {
7985
8086 // / Custom copy constructor, to ensure Range gets initialized when
8187 // / copying a constant range lattice element.
82- ValueLatticeElement (const ValueLatticeElement &Other) : Tag(undefined ) {
88+ ValueLatticeElement (const ValueLatticeElement &Other) : Tag(unknown ) {
8389 *this = Other;
8490 }
8591
@@ -109,7 +115,8 @@ class ValueLatticeElement {
109115 ConstVal = Other.ConstVal ;
110116 break ;
111117 case overdefined:
112- case undefined:
118+ case unknown:
119+ case undef:
113120 break ;
114121 }
115122 Tag = Other.Tag ;
@@ -118,14 +125,16 @@ class ValueLatticeElement {
118125
119126 static ValueLatticeElement get (Constant *C) {
120127 ValueLatticeElement Res;
121- if (!isa<UndefValue>(C))
128+ if (isa<UndefValue>(C))
129+ Res.markUndef ();
130+ else
122131 Res.markConstant (C);
123132 return Res;
124133 }
125134 static ValueLatticeElement getNot (Constant *C) {
126135 ValueLatticeElement Res;
127- if (!isa<UndefValue>(C))
128- Res.markNotConstant (C);
136+ assert (!isa<UndefValue>(C) && " != undef is not supported " );
137+ Res.markNotConstant (C);
129138 return Res;
130139 }
131140 static ValueLatticeElement getRange (ConstantRange CR) {
@@ -139,8 +148,9 @@ class ValueLatticeElement {
139148 return Res;
140149 }
141150
142- bool isUndefined () const { return Tag == undefined; }
143- bool isUnknown () const { return Tag == undefined; }
151+ bool isUndef () const { return Tag == undef; }
152+ bool isUnknown () const { return Tag == unknown; }
153+ bool isUnknownOrUndef () const { return Tag == unknown || Tag == undef; }
144154 bool isConstant () const { return Tag == constant; }
145155 bool isNotConstant () const { return Tag == notconstant; }
146156 bool isConstantRange () const { return Tag == constantrange; }
@@ -182,9 +192,18 @@ class ValueLatticeElement {
182192 return true ;
183193 }
184194
195+ bool markUndef () {
196+ if (isUndef ())
197+ return false ;
198+
199+ assert (isUnknown ());
200+ Tag = undef;
201+ return true ;
202+ }
203+
185204 bool markConstant (Constant *V) {
186205 if (isa<UndefValue>(V))
187- return false ;
206+ return markUndef () ;
188207
189208 if (isConstant ()) {
190209 assert (getConstant () == V && " Marking constant with different value" );
@@ -194,7 +213,7 @@ class ValueLatticeElement {
194213 if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
195214 return markConstantRange (ConstantRange (CI->getValue ()));
196215
197- assert (isUndefined ());
216+ assert (isUnknown () || isUndef ());
198217 Tag = constant;
199218 ConstVal = V;
200219 return true ;
@@ -214,7 +233,7 @@ class ValueLatticeElement {
214233 return false ;
215234 }
216235
217- assert (isUndefined ());
236+ assert (isUnknown ());
218237 Tag = notconstant;
219238 ConstVal = V;
220239 return true ;
@@ -223,7 +242,7 @@ class ValueLatticeElement {
223242 // / Mark the object as constant range with \p NewR. If the object is already a
224243 // / constant range, nothing changes if the existing range is equal to \p
225244 // / NewR. Otherwise \p NewR must be a superset of the existing range or the
226- // / object must be undefined .
245+ // / object must be undef .
227246 bool markConstantRange (ConstantRange NewR) {
228247 if (isConstantRange ()) {
229248 if (getConstantRange () == NewR)
@@ -238,7 +257,7 @@ class ValueLatticeElement {
238257 return true ;
239258 }
240259
241- assert (isUndefined ());
260+ assert (isUnknown () || isUndef ());
242261 if (NewR.isEmptySet ())
243262 return markOverdefined ();
244263
@@ -250,21 +269,35 @@ class ValueLatticeElement {
250269 // / Updates this object to approximate both this object and RHS. Returns
251270 // / true if this object has been changed.
252271 bool mergeIn (const ValueLatticeElement &RHS, const DataLayout &DL) {
253- if (RHS.isUndefined () || isOverdefined ())
272+ if (RHS.isUnknown () || isOverdefined ())
254273 return false ;
255274 if (RHS.isOverdefined ()) {
256275 markOverdefined ();
257276 return true ;
258277 }
259278
260- if (isUndefined ()) {
279+ if (isUndef ()) {
280+ assert (!RHS.isUnknown ());
281+ if (RHS.isUndef ())
282+ return false ;
283+ if (RHS.isConstant ())
284+ return markConstant (RHS.getConstant ());
285+ if (RHS.isConstantRange () && RHS.getConstantRange ().isSingleElement ())
286+ return markConstantRange (RHS.getConstantRange ());
287+ return markOverdefined ();
288+ }
289+
290+ if (isUnknown ()) {
291+ assert (!RHS.isUnknown () && " Unknow RHS should be handled earlier" );
261292 *this = RHS;
262- return !RHS. isUndefined () ;
293+ return true ;
263294 }
264295
265296 if (isConstant ()) {
266297 if (RHS.isConstant () && getConstant () == RHS.getConstant ())
267298 return false ;
299+ if (RHS.isUndef ())
300+ return false ;
268301 markOverdefined ();
269302 return true ;
270303 }
@@ -277,6 +310,9 @@ class ValueLatticeElement {
277310 }
278311
279312 assert (isConstantRange () && " New ValueLattice type?" );
313+ if (RHS.isUndef () && getConstantRange ().isSingleElement ())
314+ return false ;
315+
280316 if (!RHS.isConstantRange ()) {
281317 // We can get here if we've encountered a constantexpr of integer type
282318 // and merge it with a constantrange.
@@ -292,12 +328,12 @@ class ValueLatticeElement {
292328 return markConstantRange (std::move (NewR));
293329 }
294330
295- // / Compares this symbolic value with Other using Pred and returns either
331+ // Compares this symbolic value with Other using Pred and returns either
296332 // / true, false or undef constants, or nullptr if the comparison cannot be
297333 // / evaluated.
298334 Constant *getCompare (CmpInst::Predicate Pred, Type *Ty,
299335 const ValueLatticeElement &Other) const {
300- if (isUndefined () || Other.isUndefined ())
336+ if (isUnknownOrUndef () || Other.isUnknownOrUndef ())
301337 return UndefValue::get (Ty);
302338
303339 if (isConstant () && Other.isConstant ())
0 commit comments