@@ -29,7 +29,7 @@ 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 ,
3333
3434 // / This Value has a specific constant value. (For constant integers,
3535 // / constantrange is used instead. Integer typed constantexprs can appear
@@ -45,7 +45,12 @@ class ValueLatticeElement {
4545 constantrange,
4646
4747 // / We can not precisely model the dynamic values this value might take.
48- overdefined
48+ overdefined,
49+
50+ // / This Value is an UndefValue constant or produces undef. Undefined values
51+ // / can be merged with constants (or single element constant ranges),
52+ // / assuming all uses of the result will be replaced.
53+ undef
4954 };
5055
5156 ValueLatticeElementTy Tag;
@@ -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,7 +148,10 @@ class ValueLatticeElement {
139148 return Res;
140149 }
141150
142- bool isUndefined () 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; }
154+ bool isUndefined () const { return isUnknownOrUndef (); }
143155 bool isConstant () const { return Tag == constant; }
144156 bool isNotConstant () const { return Tag == notconstant; }
145157 bool isConstantRange () const { return Tag == constantrange; }
@@ -170,89 +182,123 @@ class ValueLatticeElement {
170182 return None;
171183 }
172184
173- private:
174- void markOverdefined () {
185+ bool markOverdefined () {
175186 if (isOverdefined ())
176- return ;
187+ return false ;
177188 if (isConstant () || isNotConstant ())
178189 ConstVal = nullptr ;
179190 if (isConstantRange ())
180191 Range.~ConstantRange ();
181192 Tag = overdefined;
193+ return true ;
182194 }
183195
184- void markConstant (Constant *V) {
185- assert (V && " Marking constant with NULL" );
186- if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
187- markConstantRange (ConstantRange (CI->getValue ()));
188- return ;
189- }
196+ bool markUndef () {
197+ if (isUndef ())
198+ return false ;
199+
200+ assert (isUnknown ());
201+ Tag = undef;
202+ return true ;
203+ }
204+
205+ bool markConstant (Constant *V) {
190206 if (isa<UndefValue>(V))
191- return ;
207+ return markUndef () ;
192208
193- assert ((!isConstant () || getConstant () == V) &&
194- " Marking constant with different value" );
195- assert (isUndefined ());
209+ if (isConstant ()) {
210+ assert (getConstant () == V && " Marking constant with different value" );
211+ return false ;
212+ }
213+
214+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
215+ return markConstantRange (ConstantRange (CI->getValue ()));
216+
217+ assert (isUnknown () || isUndef ());
196218 Tag = constant;
197219 ConstVal = V;
220+ return true ;
198221 }
199222
200- void markNotConstant (Constant *V) {
223+ bool markNotConstant (Constant *V) {
201224 assert (V && " Marking constant with NULL" );
202- if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
203- markConstantRange (ConstantRange (CI-> getValue () + 1 , CI-> getValue ()));
204- return ;
205- }
225+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
226+ return markConstantRange (
227+ ConstantRange (CI-> getValue () + 1 , CI-> getValue ())) ;
228+
206229 if (isa<UndefValue>(V))
207- return ;
230+ return false ;
208231
209- assert ((!isConstant () || getConstant () != V) &&
210- " Marking constant !constant with same value" );
211- assert ((!isNotConstant () || getNotConstant () == V) &&
212- " Marking !constant with different value" );
213- assert (isUndefined () || isConstant ());
232+ if (isNotConstant ()) {
233+ assert (getNotConstant () == V && " Marking !constant with different value" );
234+ return false ;
235+ }
236+
237+ assert (isUnknown ());
214238 Tag = notconstant;
215239 ConstVal = V;
240+ return true ;
216241 }
217242
218- void markConstantRange (ConstantRange NewR) {
243+ // / Mark the object as constant range with \p NewR. If the object is already a
244+ // / constant range, nothing changes if the existing range is equal to \p
245+ // / NewR. Otherwise \p NewR must be a superset of the existing range or the
246+ // / object must be undef.
247+ bool markConstantRange (ConstantRange NewR) {
219248 if (isConstantRange ()) {
249+ if (getConstantRange () == NewR)
250+ return false ;
251+
220252 if (NewR.isEmptySet ())
221- markOverdefined ();
222- else {
223- Range = std::move (NewR);
224- }
225- return ;
253+ return markOverdefined ();
254+
255+ assert (NewR.contains (getConstantRange ()) &&
256+ " Existing range must be a subset of NewR" );
257+ Range = std::move (NewR);
258+ return true ;
226259 }
227260
228- assert (isUndefined ());
261+ assert (isUnknown () || isUndef ());
229262 if (NewR.isEmptySet ())
230- markOverdefined ();
231- else {
232- Tag = constantrange;
233- new (&Range) ConstantRange (std::move (NewR));
234- }
263+ return markOverdefined ();
264+
265+ Tag = constantrange;
266+ new (&Range) ConstantRange (std::move (NewR));
267+ return true ;
235268 }
236269
237- public:
238270 // / Updates this object to approximate both this object and RHS. Returns
239271 // / true if this object has been changed.
240272 bool mergeIn (const ValueLatticeElement &RHS, const DataLayout &DL) {
241- if (RHS.isUndefined () || isOverdefined ())
273+ if (RHS.isUnknown () || isOverdefined ())
242274 return false ;
243275 if (RHS.isOverdefined ()) {
244276 markOverdefined ();
245277 return true ;
246278 }
247279
248- if (isUndefined ()) {
280+ if (isUndef ()) {
281+ assert (!RHS.isUnknown ());
282+ if (RHS.isUndef ())
283+ return false ;
284+ if (RHS.isConstant ())
285+ return markConstant (RHS.getConstant ());
286+ if (RHS.isConstantRange () && RHS.getConstantRange ().isSingleElement ())
287+ return markConstantRange (RHS.getConstantRange ());
288+ return markOverdefined ();
289+ }
290+
291+ if (isUnknown ()) {
292+ assert (!RHS.isUnknown () && " Unknow RHS should be handled earlier" );
249293 *this = RHS;
250- return !RHS. isUndefined () ;
294+ return true ;
251295 }
252296
253297 if (isConstant ()) {
254298 if (RHS.isConstant () && getConstant () == RHS.getConstant ())
255299 return false ;
300+ if (RHS.isUndef ())
301+ return false ;
256302 markOverdefined ();
257303 return true ;
258304 }
@@ -265,6 +311,9 @@ class ValueLatticeElement {
265311 }
266312
267313 assert (isConstantRange () && " New ValueLattice type?" );
314+ if (RHS.isUndef () && getConstantRange ().isSingleElement ())
315+ return false ;
316+
268317 if (!RHS.isConstantRange ()) {
269318 // We can get here if we've encountered a constantexpr of integer type
270319 // and merge it with a constantrange.
@@ -273,26 +322,19 @@ class ValueLatticeElement {
273322 }
274323 ConstantRange NewR = getConstantRange ().unionWith (RHS.getConstantRange ());
275324 if (NewR.isFullSet ())
276- markOverdefined ();
325+ return markOverdefined ();
277326 else if (NewR == getConstantRange ())
278327 return false ;
279328 else
280- markConstantRange (std::move (NewR));
281- return true ;
282- }
283-
284- ConstantInt *getConstantInt () const {
285- assert (isConstant () && isa<ConstantInt>(getConstant ()) &&
286- " No integer constant" );
287- return cast<ConstantInt>(getConstant ());
329+ return markConstantRange (std::move (NewR));
288330 }
289331
290332 // / Compares this symbolic value with Other using Pred and returns either
291333 // / true, false or undef constants, or nullptr if the comparison cannot be
292334 // / evaluated.
293335 Constant *getCompare (CmpInst::Predicate Pred, Type *Ty,
294336 const ValueLatticeElement &Other) const {
295- if (isUndefined () || Other.isUndefined ())
337+ if (isUnknownOrUndef () || Other.isUnknownOrUndef ())
296338 return UndefValue::get (Ty);
297339
298340 if (isConstant () && Other.isConstant ())
0 commit comments