@@ -29,7 +29,12 @@ class ValueLatticeElement {
29
29
// / producing instruction is dead. Caution: We use this as the starting
30
30
// / state in our local meet rules. In this usage, it's taken to mean
31
31
// / "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,
33
38
34
39
// / This Value has a specific constant value. (For constant integers,
35
40
// / constantrange is used instead. Integer typed constantexprs can appear
@@ -60,14 +65,15 @@ class ValueLatticeElement {
60
65
61
66
public:
62
67
// Const and Range are initialized on-demand.
63
- ValueLatticeElement () : Tag(undefined ) {}
68
+ ValueLatticeElement () : Tag(unknown ) {}
64
69
65
70
// / Custom destructor to ensure Range is properly destroyed, when the object
66
71
// / is deallocated.
67
72
~ValueLatticeElement () {
68
73
switch (Tag) {
69
74
case overdefined:
70
- case undefined:
75
+ case unknown:
76
+ case undef:
71
77
case constant:
72
78
case notconstant:
73
79
break ;
@@ -79,7 +85,7 @@ class ValueLatticeElement {
79
85
80
86
// / Custom copy constructor, to ensure Range gets initialized when
81
87
// / copying a constant range lattice element.
82
- ValueLatticeElement (const ValueLatticeElement &Other) : Tag(undefined ) {
88
+ ValueLatticeElement (const ValueLatticeElement &Other) : Tag(unknown ) {
83
89
*this = Other;
84
90
}
85
91
@@ -109,7 +115,8 @@ class ValueLatticeElement {
109
115
ConstVal = Other.ConstVal ;
110
116
break ;
111
117
case overdefined:
112
- case undefined:
118
+ case unknown:
119
+ case undef:
113
120
break ;
114
121
}
115
122
Tag = Other.Tag ;
@@ -118,14 +125,16 @@ class ValueLatticeElement {
118
125
119
126
static ValueLatticeElement get (Constant *C) {
120
127
ValueLatticeElement Res;
121
- if (!isa<UndefValue>(C))
128
+ if (isa<UndefValue>(C))
129
+ Res.markUndef ();
130
+ else
122
131
Res.markConstant (C);
123
132
return Res;
124
133
}
125
134
static ValueLatticeElement getNot (Constant *C) {
126
135
ValueLatticeElement Res;
127
- if (!isa<UndefValue>(C))
128
- Res.markNotConstant (C);
136
+ assert (!isa<UndefValue>(C) && " != undef is not supported " );
137
+ Res.markNotConstant (C);
129
138
return Res;
130
139
}
131
140
static ValueLatticeElement getRange (ConstantRange CR) {
@@ -139,8 +148,9 @@ class ValueLatticeElement {
139
148
return Res;
140
149
}
141
150
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; }
144
154
bool isConstant () const { return Tag == constant; }
145
155
bool isNotConstant () const { return Tag == notconstant; }
146
156
bool isConstantRange () const { return Tag == constantrange; }
@@ -182,9 +192,18 @@ class ValueLatticeElement {
182
192
return true ;
183
193
}
184
194
195
+ bool markUndef () {
196
+ if (isUndef ())
197
+ return false ;
198
+
199
+ assert (isUnknown ());
200
+ Tag = undef;
201
+ return true ;
202
+ }
203
+
185
204
bool markConstant (Constant *V) {
186
205
if (isa<UndefValue>(V))
187
- return false ;
206
+ return markUndef () ;
188
207
189
208
if (isConstant ()) {
190
209
assert (getConstant () == V && " Marking constant with different value" );
@@ -194,7 +213,7 @@ class ValueLatticeElement {
194
213
if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
195
214
return markConstantRange (ConstantRange (CI->getValue ()));
196
215
197
- assert (isUndefined ());
216
+ assert (isUnknown () || isUndef ());
198
217
Tag = constant;
199
218
ConstVal = V;
200
219
return true ;
@@ -214,7 +233,7 @@ class ValueLatticeElement {
214
233
return false ;
215
234
}
216
235
217
- assert (isUndefined ());
236
+ assert (isUnknown ());
218
237
Tag = notconstant;
219
238
ConstVal = V;
220
239
return true ;
@@ -223,7 +242,7 @@ class ValueLatticeElement {
223
242
// / Mark the object as constant range with \p NewR. If the object is already a
224
243
// / constant range, nothing changes if the existing range is equal to \p
225
244
// / NewR. Otherwise \p NewR must be a superset of the existing range or the
226
- // / object must be undefined .
245
+ // / object must be undef .
227
246
bool markConstantRange (ConstantRange NewR) {
228
247
if (isConstantRange ()) {
229
248
if (getConstantRange () == NewR)
@@ -238,7 +257,7 @@ class ValueLatticeElement {
238
257
return true ;
239
258
}
240
259
241
- assert (isUndefined ());
260
+ assert (isUnknown () || isUndef ());
242
261
if (NewR.isEmptySet ())
243
262
return markOverdefined ();
244
263
@@ -250,21 +269,35 @@ class ValueLatticeElement {
250
269
// / Updates this object to approximate both this object and RHS. Returns
251
270
// / true if this object has been changed.
252
271
bool mergeIn (const ValueLatticeElement &RHS, const DataLayout &DL) {
253
- if (RHS.isUndefined () || isOverdefined ())
272
+ if (RHS.isUnknown () || isOverdefined ())
254
273
return false ;
255
274
if (RHS.isOverdefined ()) {
256
275
markOverdefined ();
257
276
return true ;
258
277
}
259
278
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" );
261
292
*this = RHS;
262
- return !RHS. isUndefined () ;
293
+ return true ;
263
294
}
264
295
265
296
if (isConstant ()) {
266
297
if (RHS.isConstant () && getConstant () == RHS.getConstant ())
267
298
return false ;
299
+ if (RHS.isUndef ())
300
+ return false ;
268
301
markOverdefined ();
269
302
return true ;
270
303
}
@@ -277,6 +310,9 @@ class ValueLatticeElement {
277
310
}
278
311
279
312
assert (isConstantRange () && " New ValueLattice type?" );
313
+ if (RHS.isUndef () && getConstantRange ().isSingleElement ())
314
+ return false ;
315
+
280
316
if (!RHS.isConstantRange ()) {
281
317
// We can get here if we've encountered a constantexpr of integer type
282
318
// and merge it with a constantrange.
@@ -292,12 +328,12 @@ class ValueLatticeElement {
292
328
return markConstantRange (std::move (NewR));
293
329
}
294
330
295
- // / Compares this symbolic value with Other using Pred and returns either
331
+ // Compares this symbolic value with Other using Pred and returns either
296
332
// / true, false or undef constants, or nullptr if the comparison cannot be
297
333
// / evaluated.
298
334
Constant *getCompare (CmpInst::Predicate Pred, Type *Ty,
299
335
const ValueLatticeElement &Other) const {
300
- if (isUndefined () || Other.isUndefined ())
336
+ if (isUnknownOrUndef () || Other.isUnknownOrUndef ())
301
337
return UndefValue::get (Ty);
302
338
303
339
if (isConstant () && Other.isConstant ())
0 commit comments