@@ -48,6 +48,20 @@ DEBUG_COUNTER(EliminatedCounter, "conds-eliminated",
48
48
static int64_t MaxConstraintValue = std::numeric_limits<int64_t >::max();
49
49
static int64_t MinSignedConstraintValue = std::numeric_limits<int64_t >::min();
50
50
51
+ // A helper to multiply 2 signed integers where overflowing is allowed.
52
+ static int64_t multiplyWithOverflow (int64_t A, int64_t B) {
53
+ int64_t Result;
54
+ MulOverflow (A, B, Result);
55
+ return Result;
56
+ }
57
+
58
+ // A helper to add 2 signed integers where overflowing is allowed.
59
+ static int64_t addWithOverflow (int64_t A, int64_t B) {
60
+ int64_t Result;
61
+ AddOverflow (A, B, Result);
62
+ return Result;
63
+ }
64
+
51
65
namespace {
52
66
53
67
class ConstraintInfo ;
@@ -178,42 +192,55 @@ struct DecompEntry {
178
192
IsKnownPositive (IsKnownPositive) {}
179
193
};
180
194
195
+ // / Represents an Offset + Coefficient1 * Variable1 + ... decomposition.
196
+ struct Decomposition {
197
+ int64_t Offset = 0 ;
198
+ SmallVector<DecompEntry, 3 > Vars;
199
+
200
+ Decomposition (int64_t Offset) : Offset(Offset) {}
201
+ Decomposition (Value *V, bool IsKnownPositive = false ) {
202
+ Vars.emplace_back (1 , V, IsKnownPositive);
203
+ }
204
+ Decomposition (int64_t Offset, ArrayRef<DecompEntry> Vars)
205
+ : Offset(Offset), Vars(Vars) {}
206
+
207
+ void add (int64_t OtherOffset) {
208
+ Offset = addWithOverflow (Offset, OtherOffset);
209
+ }
210
+
211
+ void add (const Decomposition &Other) {
212
+ add (Other.Offset );
213
+ append_range (Vars, Other.Vars );
214
+ }
215
+
216
+ void mul (int64_t Factor) {
217
+ Offset = multiplyWithOverflow (Offset, Factor);
218
+ for (auto &Var : Vars)
219
+ Var.Coefficient = multiplyWithOverflow (Var.Coefficient , Factor);
220
+ }
221
+ };
222
+
181
223
} // namespace
182
224
183
- static SmallVector<DecompEntry, 4 >
184
- decompose (Value *V, SmallVector<PreconditionTy, 4 > &Preconditions,
185
- bool IsSigned, const DataLayout &DL);
225
+ static Decomposition decompose (Value *V,
226
+ SmallVector<PreconditionTy, 4 > &Preconditions,
227
+ bool IsSigned, const DataLayout &DL);
186
228
187
229
static bool canUseSExt (ConstantInt *CI) {
188
230
const APInt &Val = CI->getValue ();
189
231
return Val.sgt (MinSignedConstraintValue) && Val.slt (MaxConstraintValue);
190
232
}
191
233
192
- // A helper to multiply 2 signed integers where overflowing is allowed.
193
- static int64_t multiplyWithOverflow (int64_t A, int64_t B) {
194
- int64_t Result;
195
- MulOverflow (A, B, Result);
196
- return Result;
197
- }
198
-
199
- // A helper to add 2 signed integers where overflowing is allowed.
200
- static int64_t addWithOverflow (int64_t A, int64_t B) {
201
- int64_t Result;
202
- AddOverflow (A, B, Result);
203
- return Result;
204
- }
205
-
206
- static SmallVector<DecompEntry, 4 >
207
- decomposeGEP (GetElementPtrInst &GEP,
208
- SmallVector<PreconditionTy, 4 > &Preconditions, bool IsSigned,
209
- const DataLayout &DL) {
234
+ static Decomposition decomposeGEP (GetElementPtrInst &GEP,
235
+ SmallVector<PreconditionTy, 4 > &Preconditions,
236
+ bool IsSigned, const DataLayout &DL) {
210
237
// Do not reason about pointers where the index size is larger than 64 bits,
211
238
// as the coefficients used to encode constraints are 64 bit integers.
212
239
if (DL.getIndexTypeSizeInBits (GEP.getPointerOperand ()->getType ()) > 64 )
213
- return {{ 0 , nullptr }, { 1 , &GEP}} ;
240
+ return &GEP;
214
241
215
242
if (!GEP.isInBounds ())
216
- return {{ 0 , nullptr }, { 1 , &GEP}} ;
243
+ return &GEP;
217
244
218
245
// Handle the (gep (gep ....), C) case by incrementing the constant
219
246
// coefficient of the inner GEP, if C is a constant.
@@ -226,13 +253,11 @@ decomposeGEP(GetElementPtrInst &GEP,
226
253
auto GTI = gep_type_begin (GEP);
227
254
// Bail out for scalable vectors for now.
228
255
if (isa<ScalableVectorType>(GTI.getIndexedType ()))
229
- return {{ 0 , nullptr }, { 1 , &GEP}} ;
256
+ return &GEP;
230
257
int64_t Scale = static_cast <int64_t >(
231
258
DL.getTypeAllocSize (GTI.getIndexedType ()).getFixedSize ());
232
259
233
- Result[0 ].Coefficient =
234
- addWithOverflow (Result[0 ].Coefficient ,
235
- multiplyWithOverflow (Scale, Offset.getSExtValue ()));
260
+ Result.add (multiplyWithOverflow (Scale, Offset.getSExtValue ()));
236
261
if (Offset.isNegative ()) {
237
262
// Add pre-condition ensuring the GEP is increasing monotonically and
238
263
// can be de-composed.
@@ -244,16 +269,15 @@ decomposeGEP(GetElementPtrInst &GEP,
244
269
return Result;
245
270
}
246
271
247
- SmallVector<DecompEntry, 4 > Result = {{0 , nullptr },
248
- {1 , GEP.getPointerOperand ()}};
272
+ Decomposition Result = GEP.getPointerOperand ();
249
273
gep_type_iterator GTI = gep_type_begin (GEP);
250
274
for (User::const_op_iterator I = GEP.op_begin () + 1 , E = GEP.op_end (); I != E;
251
275
++I, ++GTI) {
252
276
Value *Index = *I;
253
277
254
278
// Bail out for scalable vectors for now.
255
279
if (isa<ScalableVectorType>(GTI.getIndexedType ()))
256
- return {{ 0 , nullptr }, { 1 , &GEP}} ;
280
+ return &GEP;
257
281
258
282
// Struct indices must be constants (and reference an existing field). Add
259
283
// them to the constant factor.
@@ -264,20 +288,16 @@ decomposeGEP(GetElementPtrInst &GEP,
264
288
continue ;
265
289
266
290
// Add offset to constant factor.
267
- Result[0 ].Coefficient = addWithOverflow (
268
- Result[0 ].Coefficient ,
269
- int64_t (DL.getStructLayout (STy)->getElementOffset (FieldNo)));
291
+ Result.add (int64_t (DL.getStructLayout (STy)->getElementOffset (FieldNo)));
270
292
continue ;
271
293
}
272
294
273
295
// For an array/pointer, add the element offset, explicitly scaled.
274
296
unsigned Scale = DL.getTypeAllocSize (GTI.getIndexedType ()).getFixedSize ();
275
297
276
298
auto IdxResult = decompose (Index, Preconditions, IsSigned, DL);
277
- for (auto &KV : IdxResult)
278
- KV.Coefficient = multiplyWithOverflow (KV.Coefficient , Scale);
279
- Result[0 ].Coefficient += IdxResult[0 ].Coefficient ;
280
- append_range (Result, ArrayRef<DecompEntry>(IdxResult).drop_front ());
299
+ IdxResult.mul (Scale);
300
+ Result.add (IdxResult);
281
301
282
302
// If Op0 is signed non-negative, the GEP is increasing monotonically and
283
303
// can be de-composed.
@@ -292,38 +312,36 @@ decomposeGEP(GetElementPtrInst &GEP,
292
312
// } where Coefficient * Variable. The sum of the pairs equals \p V. The first
293
313
// pair is the constant-factor and X must be nullptr. If the expression cannot
294
314
// be decomposed, returns an empty vector.
295
- static SmallVector<DecompEntry, 4 >
296
- decompose (Value *V, SmallVector<PreconditionTy, 4 > &Preconditions,
297
- bool IsSigned, const DataLayout &DL) {
315
+ static Decomposition decompose (Value *V,
316
+ SmallVector<PreconditionTy, 4 > &Preconditions,
317
+ bool IsSigned, const DataLayout &DL) {
298
318
299
- auto MergeResults = [&Preconditions, IsSigned,
300
- &DL](Value *A, Value *B,
301
- bool IsSignedB) -> SmallVector<DecompEntry, 4 > {
319
+ auto MergeResults = [&Preconditions, IsSigned, &DL](Value *A, Value *B,
320
+ bool IsSignedB) {
302
321
auto ResA = decompose (A, Preconditions, IsSigned, DL);
303
322
auto ResB = decompose (B, Preconditions, IsSignedB, DL);
304
- ResA[0 ].Coefficient += ResB[0 ].Coefficient ;
305
- append_range (ResA, drop_begin (ResB));
323
+ ResA.add (ResB);
306
324
return ResA;
307
325
};
308
326
309
327
// Decompose \p V used with a signed predicate.
310
328
if (IsSigned) {
311
329
if (auto *CI = dyn_cast<ConstantInt>(V)) {
312
330
if (canUseSExt (CI))
313
- return {{ CI->getSExtValue (), nullptr }} ;
331
+ return CI->getSExtValue ();
314
332
}
315
333
Value *Op0;
316
334
Value *Op1;
317
335
if (match (V, m_NSWAdd (m_Value (Op0), m_Value (Op1))))
318
336
return MergeResults (Op0, Op1, IsSigned);
319
337
320
- return {{ 0 , nullptr }, { 1 , V}} ;
338
+ return V ;
321
339
}
322
340
323
341
if (auto *CI = dyn_cast<ConstantInt>(V)) {
324
342
if (CI->uge (MaxConstraintValue))
325
- return {{ 0 , nullptr }, { 1 , V}} ;
326
- return {{ int64_t (CI->getZExtValue ()), nullptr }} ;
343
+ return V ;
344
+ return int64_t (CI->getZExtValue ());
327
345
}
328
346
329
347
if (auto *GEP = dyn_cast<GetElementPtrInst>(V))
@@ -363,25 +381,23 @@ decompose(Value *V, SmallVector<PreconditionTy, 4> &Preconditions,
363
381
if (match (V, m_NUWShl (m_Value (Op1), m_ConstantInt (CI))) && canUseSExt (CI)) {
364
382
int64_t Mult = int64_t (std::pow (int64_t (2 ), CI->getSExtValue ()));
365
383
auto Result = decompose (Op1, Preconditions, IsSigned, DL);
366
- for (auto &KV : Result)
367
- KV.Coefficient *= Mult;
384
+ Result.mul (Mult);
368
385
return Result;
369
386
}
370
387
371
388
if (match (V, m_NUWMul (m_Value (Op1), m_ConstantInt (CI))) && canUseSExt (CI) &&
372
389
(!CI->isNegative ())) {
373
390
auto Result = decompose (Op1, Preconditions, IsSigned, DL);
374
- for (auto &KV : Result)
375
- KV.Coefficient *= CI->getSExtValue ();
391
+ Result.mul (CI->getSExtValue ());
376
392
return Result;
377
393
}
378
394
379
395
if (match (V, m_NUWSub (m_Value (Op0), m_ConstantInt (CI))) && canUseSExt (CI))
380
- return {{ -1 * CI->getSExtValue (), nullptr }, { 1 , Op0}};
396
+ return {-1 * CI->getSExtValue (), {{ 1 , Op0} }};
381
397
if (match (V, m_NUWSub (m_Value (Op0), m_Value (Op1))))
382
- return {{ 0 , nullptr }, { 1 , Op0}, {-1 , Op1}};
398
+ return {0 , {{ 1 , Op0}, {-1 , Op1} }};
383
399
384
- return {{ 0 , nullptr }, { 1 , V, IsKnownPositive} };
400
+ return {V, IsKnownPositive};
385
401
}
386
402
387
403
ConstraintTy
@@ -429,13 +445,12 @@ ConstraintInfo::getConstraint(CmpInst::Predicate Pred, Value *Op0, Value *Op1,
429
445
Preconditions, IsSigned, DL);
430
446
auto BDec = decompose (Op1->stripPointerCastsSameRepresentation (),
431
447
Preconditions, IsSigned, DL);
432
- int64_t Offset1 = ADec[ 0 ]. Coefficient ;
433
- int64_t Offset2 = BDec[ 0 ]. Coefficient ;
448
+ int64_t Offset1 = ADec. Offset ;
449
+ int64_t Offset2 = BDec. Offset ;
434
450
Offset1 *= -1 ;
435
451
436
- // Create iterator ranges that skip the constant-factor.
437
- auto VariablesA = llvm::drop_begin (ADec);
438
- auto VariablesB = llvm::drop_begin (BDec);
452
+ auto &VariablesA = ADec.Vars ;
453
+ auto &VariablesB = BDec.Vars ;
439
454
440
455
// First try to look up \p V in Value2Index and NewVariables. Otherwise add a
441
456
// new entry to NewVariables.
0 commit comments