@@ -1269,9 +1269,6 @@ static Value *simplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
1269
1269
// ... ...
1270
1270
// \ /
1271
1271
// phi [true] [false]
1272
- if (!PN.getType ()->isIntegerTy (1 ))
1273
- return nullptr ;
1274
-
1275
1272
// Make sure all inputs are constants.
1276
1273
if (!all_of (PN.operands (), [](Value *V) { return isa<ConstantInt>(V); }))
1277
1274
return nullptr ;
@@ -1281,30 +1278,56 @@ static Value *simplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
1281
1278
if (!DT.isReachableFromEntry (BB))
1282
1279
return nullptr ;
1283
1280
1284
- // Check that the immediate dominator has a conditional branch.
1281
+ // Determine which value the condition of the idom has for which successor.
1282
+ LLVMContext &Context = PN.getContext ();
1285
1283
auto *IDom = DT.getNode (BB)->getIDom ()->getBlock ();
1286
- auto *BI = dyn_cast<BranchInst>(IDom->getTerminator ());
1287
- if (!BI || BI->isUnconditional ())
1284
+ Value *Cond;
1285
+ SmallDenseMap<ConstantInt *, BasicBlock *, 8 > SuccForValue;
1286
+ SmallDenseMap<BasicBlock *, unsigned , 8 > SuccCount;
1287
+ auto AddSucc = [&](ConstantInt *C, BasicBlock *Succ) {
1288
+ SuccForValue[C] = Succ;
1289
+ ++SuccCount[Succ];
1290
+ };
1291
+ if (auto *BI = dyn_cast<BranchInst>(IDom->getTerminator ())) {
1292
+ if (BI->isUnconditional ())
1293
+ return nullptr ;
1294
+
1295
+ Cond = BI->getCondition ();
1296
+ AddSucc (ConstantInt::getTrue (Context), BI->getSuccessor (0 ));
1297
+ AddSucc (ConstantInt::getFalse (Context), BI->getSuccessor (1 ));
1298
+ } else if (auto *SI = dyn_cast<SwitchInst>(IDom->getTerminator ())) {
1299
+ Cond = SI->getCondition ();
1300
+ for (auto Case : SI->cases ())
1301
+ AddSucc (Case.getCaseValue (), Case.getCaseSuccessor ());
1302
+ } else {
1303
+ return nullptr ;
1304
+ }
1305
+
1306
+ if (Cond->getType () != PN.getType ())
1288
1307
return nullptr ;
1289
1308
1290
1309
// Check that edges outgoing from the idom's terminators dominate respective
1291
1310
// inputs of the Phi.
1292
- BasicBlockEdge TrueOutEdge (IDom, BI->getSuccessor (0 ));
1293
- BasicBlockEdge FalseOutEdge (IDom, BI->getSuccessor (1 ));
1294
-
1295
1311
Optional<bool > Invert;
1296
1312
for (auto Pair : zip (PN.incoming_values (), PN.blocks ())) {
1297
1313
auto *Input = cast<ConstantInt>(std::get<0 >(Pair));
1298
1314
BasicBlock *Pred = std::get<1 >(Pair);
1299
- BasicBlockEdge Edge (Pred, BB);
1315
+ auto IsCorrectInput = [&](ConstantInt *Input) {
1316
+ // The input needs to be dominated by the corresponding edge of the idom.
1317
+ // This edge cannot be a multi-edge, as that would imply that multiple
1318
+ // different condition values follow the same edge.
1319
+ auto It = SuccForValue.find (Input);
1320
+ return It != SuccForValue.end () && SuccCount[It->second ] == 1 &&
1321
+ DT.dominates (BasicBlockEdge (IDom, It->second ),
1322
+ BasicBlockEdge (Pred, BB));
1323
+ };
1300
1324
1301
- // The input needs to be dominated by one of the edges of the idom.
1302
1325
// Depending on the constant, the condition may need to be inverted.
1303
1326
bool NeedsInvert;
1304
- if (DT. dominates (TrueOutEdge, Edge ))
1305
- NeedsInvert = Input-> isZero () ;
1306
- else if (DT. dominates (FalseOutEdge, Edge ))
1307
- NeedsInvert = Input-> isOne () ;
1327
+ if (IsCorrectInput (Input ))
1328
+ NeedsInvert = false ;
1329
+ else if (IsCorrectInput (cast<ConstantInt>( ConstantExpr::getNot (Input)) ))
1330
+ NeedsInvert = true ;
1308
1331
else
1309
1332
return nullptr ;
1310
1333
@@ -1315,7 +1338,6 @@ static Value *simplifyUsingControlFlow(InstCombiner &Self, PHINode &PN,
1315
1338
Invert = NeedsInvert;
1316
1339
}
1317
1340
1318
- auto *Cond = BI->getCondition ();
1319
1341
if (!*Invert)
1320
1342
return Cond;
1321
1343
0 commit comments