@@ -434,6 +434,28 @@ class LazyValueInfoImpl {
434
434
435
435
void solve ();
436
436
437
+ // For the following methods, if UseBlockValue is true, the function may
438
+ // push additional values to the worklist and return nullopt. If
439
+ // UseBlockValue is false, it will never return nullopt.
440
+
441
+ std::optional<ValueLatticeElement>
442
+ getValueFromSimpleICmpCondition (CmpInst::Predicate Pred, Value *RHS,
443
+ const APInt &Offset, Instruction *CxtI,
444
+ bool UseBlockValue);
445
+
446
+ std::optional<ValueLatticeElement>
447
+ getValueFromICmpCondition (Value *Val, ICmpInst *ICI, bool isTrueDest,
448
+ bool UseBlockValue);
449
+
450
+ std::optional<ValueLatticeElement>
451
+ getValueFromCondition (Value *Val, Value *Cond, bool IsTrueDest,
452
+ bool UseBlockValue, unsigned Depth = 0 );
453
+
454
+ std::optional<ValueLatticeElement> getEdgeValueLocal (Value *Val,
455
+ BasicBlock *BBFrom,
456
+ BasicBlock *BBTo,
457
+ bool UseBlockValue);
458
+
437
459
public:
438
460
// / This is the query interface to determine the lattice value for the
439
461
// / specified Value* at the context instruction (if specified) or at the
@@ -755,14 +777,10 @@ LazyValueInfoImpl::solveBlockValuePHINode(PHINode *PN, BasicBlock *BB) {
755
777
return Result;
756
778
}
757
779
758
- static ValueLatticeElement getValueFromCondition (Value *Val, Value *Cond,
759
- bool isTrueDest = true ,
760
- unsigned Depth = 0 );
761
-
762
780
// If we can determine a constraint on the value given conditions assumed by
763
781
// the program, intersect those constraints with BBLV
764
782
void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange (
765
- Value *Val, ValueLatticeElement &BBLV, Instruction *BBI) {
783
+ Value *Val, ValueLatticeElement &BBLV, Instruction *BBI) {
766
784
BBI = BBI ? BBI : dyn_cast<Instruction>(Val);
767
785
if (!BBI)
768
786
return ;
@@ -779,17 +797,21 @@ void LazyValueInfoImpl::intersectAssumeOrGuardBlockValueConstantRange(
779
797
if (I->getParent () != BB || !isValidAssumeForContext (I, BBI))
780
798
continue ;
781
799
782
- BBLV = intersect (BBLV, getValueFromCondition (Val, I->getArgOperand (0 )));
800
+ BBLV = intersect (BBLV, *getValueFromCondition (Val, I->getArgOperand (0 ),
801
+ /* IsTrueDest*/ true ,
802
+ /* UseBlockValue*/ false ));
783
803
}
784
804
785
805
// If guards are not used in the module, don't spend time looking for them
786
806
if (GuardDecl && !GuardDecl->use_empty () &&
787
807
BBI->getIterator () != BB->begin ()) {
788
- for (Instruction &I : make_range ( std::next (BBI-> getIterator (). getReverse ()),
789
- BB->rend ())) {
808
+ for (Instruction &I :
809
+ make_range ( std::next (BBI-> getIterator (). getReverse ()), BB->rend ())) {
790
810
Value *Cond = nullptr ;
791
811
if (match (&I, m_Intrinsic<Intrinsic::experimental_guard>(m_Value (Cond))))
792
- BBLV = intersect (BBLV, getValueFromCondition (Val, Cond));
812
+ BBLV = intersect (BBLV,
813
+ *getValueFromCondition (Val, Cond, /* IsTrueDest*/ true ,
814
+ /* UseBlockValue*/ false ));
793
815
}
794
816
}
795
817
@@ -886,10 +908,14 @@ LazyValueInfoImpl::solveBlockValueSelect(SelectInst *SI, BasicBlock *BB) {
886
908
// If the value is undef, a different value may be chosen in
887
909
// the select condition.
888
910
if (isGuaranteedNotToBeUndef (Cond, AC)) {
889
- TrueVal = intersect (TrueVal,
890
- getValueFromCondition (SI->getTrueValue (), Cond, true ));
891
- FalseVal = intersect (
892
- FalseVal, getValueFromCondition (SI->getFalseValue (), Cond, false ));
911
+ TrueVal =
912
+ intersect (TrueVal, *getValueFromCondition (SI->getTrueValue (), Cond,
913
+ /* IsTrueDest*/ true ,
914
+ /* UseBlockValue*/ false ));
915
+ FalseVal =
916
+ intersect (FalseVal, *getValueFromCondition (SI->getFalseValue (), Cond,
917
+ /* IsTrueDest*/ false ,
918
+ /* UseBlockValue*/ false ));
893
919
}
894
920
895
921
ValueLatticeElement Result = TrueVal;
@@ -1068,15 +1094,26 @@ static bool matchICmpOperand(APInt &Offset, Value *LHS, Value *Val,
1068
1094
}
1069
1095
1070
1096
// / Get value range for a "(Val + Offset) Pred RHS" condition.
1071
- static ValueLatticeElement getValueFromSimpleICmpCondition (
1072
- CmpInst::Predicate Pred, Value *RHS, const APInt &Offset) {
1097
+ std::optional<ValueLatticeElement>
1098
+ LazyValueInfoImpl::getValueFromSimpleICmpCondition (CmpInst::Predicate Pred,
1099
+ Value *RHS,
1100
+ const APInt &Offset,
1101
+ Instruction *CxtI,
1102
+ bool UseBlockValue) {
1073
1103
ConstantRange RHSRange (RHS->getType ()->getIntegerBitWidth (),
1074
1104
/* isFullSet=*/ true );
1075
- if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS))
1105
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(RHS)) {
1076
1106
RHSRange = ConstantRange (CI->getValue ());
1077
- else if (Instruction *I = dyn_cast<Instruction>(RHS))
1107
+ } else if (UseBlockValue) {
1108
+ std::optional<ValueLatticeElement> R =
1109
+ getBlockValue (RHS, CxtI->getParent (), CxtI);
1110
+ if (!R)
1111
+ return std::nullopt;
1112
+ RHSRange = toConstantRange (*R, RHS->getType ());
1113
+ } else if (Instruction *I = dyn_cast<Instruction>(RHS)) {
1078
1114
if (auto *Ranges = I->getMetadata (LLVMContext::MD_range))
1079
1115
RHSRange = getConstantRangeFromMetadata (*Ranges);
1116
+ }
1080
1117
1081
1118
ConstantRange TrueValues =
1082
1119
ConstantRange::makeAllowedICmpRegion (Pred, RHSRange);
@@ -1103,8 +1140,8 @@ getRangeViaSLT(CmpInst::Predicate Pred, APInt RHS,
1103
1140
return std::nullopt;
1104
1141
}
1105
1142
1106
- static ValueLatticeElement getValueFromICmpCondition (Value *Val, ICmpInst *ICI,
1107
- bool isTrueDest ) {
1143
+ std::optional< ValueLatticeElement> LazyValueInfoImpl:: getValueFromICmpCondition (
1144
+ Value *Val, ICmpInst *ICI, bool isTrueDest, bool UseBlockValue ) {
1108
1145
Value *LHS = ICI->getOperand (0 );
1109
1146
Value *RHS = ICI->getOperand (1 );
1110
1147
@@ -1128,11 +1165,13 @@ static ValueLatticeElement getValueFromICmpCondition(Value *Val, ICmpInst *ICI,
1128
1165
unsigned BitWidth = Ty->getScalarSizeInBits ();
1129
1166
APInt Offset (BitWidth, 0 );
1130
1167
if (matchICmpOperand (Offset, LHS, Val, EdgePred))
1131
- return getValueFromSimpleICmpCondition (EdgePred, RHS, Offset);
1168
+ return getValueFromSimpleICmpCondition (EdgePred, RHS, Offset, ICI,
1169
+ UseBlockValue);
1132
1170
1133
1171
CmpInst::Predicate SwappedPred = CmpInst::getSwappedPredicate (EdgePred);
1134
1172
if (matchICmpOperand (Offset, RHS, Val, SwappedPred))
1135
- return getValueFromSimpleICmpCondition (SwappedPred, LHS, Offset);
1173
+ return getValueFromSimpleICmpCondition (SwappedPred, LHS, Offset, ICI,
1174
+ UseBlockValue);
1136
1175
1137
1176
const APInt *Mask, *C;
1138
1177
if (match (LHS, m_And (m_Specific (Val), m_APInt (Mask))) &&
@@ -1212,10 +1251,12 @@ static ValueLatticeElement getValueFromOverflowCondition(
1212
1251
return ValueLatticeElement::getRange (NWR);
1213
1252
}
1214
1253
1215
- static ValueLatticeElement getValueFromCondition (
1216
- Value *Val, Value *Cond, bool IsTrueDest, unsigned Depth) {
1254
+ std::optional<ValueLatticeElement>
1255
+ LazyValueInfoImpl::getValueFromCondition (Value *Val, Value *Cond,
1256
+ bool IsTrueDest, bool UseBlockValue,
1257
+ unsigned Depth) {
1217
1258
if (ICmpInst *ICI = dyn_cast<ICmpInst>(Cond))
1218
- return getValueFromICmpCondition (Val, ICI, IsTrueDest);
1259
+ return getValueFromICmpCondition (Val, ICI, IsTrueDest, UseBlockValue );
1219
1260
1220
1261
if (auto *EVI = dyn_cast<ExtractValueInst>(Cond))
1221
1262
if (auto *WO = dyn_cast<WithOverflowInst>(EVI->getAggregateOperand ()))
@@ -1227,7 +1268,7 @@ static ValueLatticeElement getValueFromCondition(
1227
1268
1228
1269
Value *N;
1229
1270
if (match (Cond, m_Not (m_Value (N))))
1230
- return getValueFromCondition (Val, N, !IsTrueDest, Depth);
1271
+ return getValueFromCondition (Val, N, !IsTrueDest, UseBlockValue, Depth);
1231
1272
1232
1273
Value *L, *R;
1233
1274
bool IsAnd;
@@ -1238,19 +1279,23 @@ static ValueLatticeElement getValueFromCondition(
1238
1279
else
1239
1280
return ValueLatticeElement::getOverdefined ();
1240
1281
1241
- ValueLatticeElement LV = getValueFromCondition (Val, L, IsTrueDest, Depth);
1242
- ValueLatticeElement RV = getValueFromCondition (Val, R, IsTrueDest, Depth);
1282
+ std::optional<ValueLatticeElement> LV =
1283
+ getValueFromCondition (Val, L, IsTrueDest, UseBlockValue, Depth);
1284
+ std::optional<ValueLatticeElement> RV =
1285
+ getValueFromCondition (Val, R, IsTrueDest, UseBlockValue, Depth);
1286
+ if (!LV || !RV)
1287
+ return std::nullopt;
1243
1288
1244
1289
// if (L && R) -> intersect L and R
1245
1290
// if (!(L || R)) -> intersect !L and !R
1246
1291
// if (L || R) -> union L and R
1247
1292
// if (!(L && R)) -> union !L and !R
1248
1293
if (IsTrueDest ^ IsAnd) {
1249
- LV. mergeIn (RV);
1250
- return LV;
1294
+ LV-> mergeIn (* RV);
1295
+ return * LV;
1251
1296
}
1252
1297
1253
- return intersect (LV, RV);
1298
+ return intersect (* LV, * RV);
1254
1299
}
1255
1300
1256
1301
// Return true if Usr has Op as an operand, otherwise false.
@@ -1302,8 +1347,9 @@ static ValueLatticeElement constantFoldUser(User *Usr, Value *Op,
1302
1347
}
1303
1348
1304
1349
// / Compute the value of Val on the edge BBFrom -> BBTo.
1305
- static ValueLatticeElement getEdgeValueLocal (Value *Val, BasicBlock *BBFrom,
1306
- BasicBlock *BBTo) {
1350
+ std::optional<ValueLatticeElement>
1351
+ LazyValueInfoImpl::getEdgeValueLocal (Value *Val, BasicBlock *BBFrom,
1352
+ BasicBlock *BBTo, bool UseBlockValue) {
1307
1353
// TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we
1308
1354
// know that v != 0.
1309
1355
if (BranchInst *BI = dyn_cast<BranchInst>(BBFrom->getTerminator ())) {
@@ -1324,13 +1370,16 @@ static ValueLatticeElement getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
1324
1370
1325
1371
// If the condition of the branch is an equality comparison, we may be
1326
1372
// able to infer the value.
1327
- ValueLatticeElement Result = getValueFromCondition (Val, Condition,
1328
- isTrueDest);
1329
- if (!Result.isOverdefined ())
1373
+ std::optional<ValueLatticeElement> Result =
1374
+ getValueFromCondition (Val, Condition, isTrueDest, UseBlockValue);
1375
+ if (!Result)
1376
+ return std::nullopt;
1377
+
1378
+ if (!Result->isOverdefined ())
1330
1379
return Result;
1331
1380
1332
1381
if (User *Usr = dyn_cast<User>(Val)) {
1333
- assert (Result. isOverdefined () && " Result isn't overdefined" );
1382
+ assert (Result-> isOverdefined () && " Result isn't overdefined" );
1334
1383
// Check with isOperationFoldable() first to avoid linearly iterating
1335
1384
// over the operands unnecessarily which can be expensive for
1336
1385
// instructions with many operands.
@@ -1356,8 +1405,8 @@ static ValueLatticeElement getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
1356
1405
// br i1 %Condition, label %then, label %else
1357
1406
for (unsigned i = 0 ; i < Usr->getNumOperands (); ++i) {
1358
1407
Value *Op = Usr->getOperand (i);
1359
- ValueLatticeElement OpLatticeVal =
1360
- getValueFromCondition ( Op, Condition, isTrueDest);
1408
+ ValueLatticeElement OpLatticeVal = * getValueFromCondition (
1409
+ Op, Condition, isTrueDest, /* UseBlockValue */ false );
1361
1410
if (std::optional<APInt> OpConst =
1362
1411
OpLatticeVal.asConstantInteger ()) {
1363
1412
Result = constantFoldUser (Usr, Op, *OpConst, DL);
@@ -1367,7 +1416,7 @@ static ValueLatticeElement getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
1367
1416
}
1368
1417
}
1369
1418
}
1370
- if (!Result. isOverdefined ())
1419
+ if (!Result-> isOverdefined ())
1371
1420
return Result;
1372
1421
}
1373
1422
}
@@ -1432,8 +1481,12 @@ LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
1432
1481
if (Constant *VC = dyn_cast<Constant>(Val))
1433
1482
return ValueLatticeElement::get (VC);
1434
1483
1435
- ValueLatticeElement LocalResult = getEdgeValueLocal (Val, BBFrom, BBTo);
1436
- if (hasSingleValue (LocalResult))
1484
+ std::optional<ValueLatticeElement> LocalResult =
1485
+ getEdgeValueLocal (Val, BBFrom, BBTo, /* UseBlockValue*/ true );
1486
+ if (!LocalResult)
1487
+ return std::nullopt;
1488
+
1489
+ if (hasSingleValue (*LocalResult))
1437
1490
// Can't get any more precise here
1438
1491
return LocalResult;
1439
1492
@@ -1453,7 +1506,7 @@ LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
1453
1506
// but then the result is not cached.
1454
1507
intersectAssumeOrGuardBlockValueConstantRange (Val, InBlock, CxtI);
1455
1508
1456
- return intersect (LocalResult, InBlock);
1509
+ return intersect (* LocalResult, InBlock);
1457
1510
}
1458
1511
1459
1512
ValueLatticeElement LazyValueInfoImpl::getValueInBlock (Value *V, BasicBlock *BB,
@@ -1499,10 +1552,12 @@ getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
1499
1552
1500
1553
std::optional<ValueLatticeElement> Result =
1501
1554
getEdgeValue (V, FromBB, ToBB, CxtI);
1502
- if (!Result) {
1555
+ while (!Result) {
1556
+ // As the worklist only explicitly tracks block values (but not edge values)
1557
+ // we may have to call solve() multiple times, as the edge value calculation
1558
+ // may request additional block values.
1503
1559
solve ();
1504
1560
Result = getEdgeValue (V, FromBB, ToBB, CxtI);
1505
- assert (Result && " More work to do after problem solved?" );
1506
1561
}
1507
1562
1508
1563
LLVM_DEBUG (dbgs () << " Result = " << *Result << " \n " );
@@ -1528,13 +1583,17 @@ ValueLatticeElement LazyValueInfoImpl::getValueAtUse(const Use &U) {
1528
1583
if (!isGuaranteedNotToBeUndef (SI->getCondition (), AC))
1529
1584
break ;
1530
1585
if (CurrU->getOperandNo () == 1 )
1531
- CondVal = getValueFromCondition (V, SI->getCondition (), true );
1586
+ CondVal =
1587
+ *getValueFromCondition (V, SI->getCondition (), /* IsTrueDest*/ true ,
1588
+ /* UseBlockValue*/ false );
1532
1589
else if (CurrU->getOperandNo () == 2 )
1533
- CondVal = getValueFromCondition (V, SI->getCondition (), false );
1590
+ CondVal =
1591
+ *getValueFromCondition (V, SI->getCondition (), /* IsTrueDest*/ false ,
1592
+ /* UseBlockValue*/ false );
1534
1593
} else if (auto *PHI = dyn_cast<PHINode>(CurrI)) {
1535
1594
// TODO: Use non-local query?
1536
- CondVal =
1537
- getEdgeValueLocal (V, PHI-> getIncomingBlock (*CurrU), PHI->getParent ());
1595
+ CondVal = * getEdgeValueLocal (V, PHI-> getIncomingBlock (*CurrU),
1596
+ PHI->getParent (), /* UseBlockValue */ false );
1538
1597
}
1539
1598
if (CondVal)
1540
1599
VL = intersect (VL, *CondVal);
0 commit comments