[llvm] [PredicateInfo] Support `PredicateInfo` by adding `PHI` nodes that pick up info from created branch predicates (PR #151132)

Yingwei Zheng via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 12 07:57:06 PST 2025


================
@@ -460,6 +471,114 @@ void PredicateInfoBuilder::processSwitch(
   }
 }
 
+void PredicateInfoBuilder::identifyPHICandidates(
+    SmallVectorImpl<Value *> &OpsToRename) {
+  for (Value *Op : OpsToRename) {
+    const auto &ValueInfo = getValueInfo(Op);
+    SmallPtrSet<BasicBlock *, 4> DefiningBlocks;
+    for (const auto *PInfo : ValueInfo.Infos) {
+      if (auto *PBranch = dyn_cast<PredicateBranch>(PInfo)) {
+        DefiningBlocks.insert(PBranch->From);
+      } else if (auto *PSwitch = dyn_cast<PredicateSwitch>(PInfo)) {
+        DefiningBlocks.insert(PSwitch->From);
+      }
+    }
+
+    if (DefiningBlocks.size() > 1) {
+      SmallPtrSet<BasicBlock *, 8> PHIBlocks;
+      needsPHIInsertion(Op, DefiningBlocks, PHIBlocks);
+      for (BasicBlock *PHIBlock : PHIBlocks) {
+        PHICandidates[PHIBlock].push_back(Op);
+      }
+    }
+  }
+}
+
+void PredicateInfoBuilder::needsPHIInsertion(
+    Value *Op, const SmallPtrSetImpl<BasicBlock *> &DefiningBlocks,
+    SmallPtrSetImpl<BasicBlock *> &PHIBlocks) {
+  IDFCalculator<false> IDF(DT);
+  IDF.setDefiningBlocks(DefiningBlocks);
+
+  SmallPtrSet<BasicBlock *, 8> LiveInBlocks;
+  for (auto CurUser = Op->users().begin(); CurUser != Op->users().end();
+       ++CurUser) {
+    if (auto *I = dyn_cast<Instruction>(*CurUser)) {
+      LiveInBlocks.insert(I->getParent());
+    }
+  }
+  IDF.setLiveInBlocks(LiveInBlocks);
+
+  SmallVector<BasicBlock *, 4> IDFBlocks;
+  IDF.calculate(IDFBlocks);
+
+  for (const auto &IDFBlock : IDFBlocks) {
+    PHIBlocks.insert(std::move(IDFBlock));
+  }
+}
+
+PHINode *PredicateInfoBuilder::insertPredicatePHIs(
+    Value *Op, BasicBlock *PHIBlock, SmallVectorImpl<Value *> &OpsToRename) {
+  IRBuilder<> Builder(&PHIBlock->front());
+
+  PHINode *PHI = Builder.CreatePHI(Op->getType(), pred_size(PHIBlock),
+                                   Op->getName() + ".predicate.phi");
+  const auto &ValueInfo = getValueInfo(Op);
+
+  for (BasicBlock *Pred : predecessors(PHIBlock)) {
----------------
dtcxzyw wrote:

Doesn't it support phi incoming values? Consider the following case:
```

@p = local_unnamed_addr global i32 0

define noundef i32 @h5diff(i32 %0, i1 %1, i1 %2) local_unnamed_addr #0 {
entry:
  %cond = icmp eq i32 %0, 0
  br i1 %1, label %3, label %4

3:
  store i32 1, ptr @p, align 4
  br i1 %2, label %a, label %b

a:
  br i1 %cond, label %c, label %common.ret

b:
  br i1 %cond, label %c, label %common.ret

c:
  br label %5

common.ret:
  ret i32 0

4:
  store i32 2, ptr @p, align 4
  br i1 %cond, label %5, label %common.ret

5:
  store i32 %0, ptr @p, align 4
  br label %common.ret
}
``` 
Two phi nodes should be inserted:
```
c:
  %phi = phi i32 [ %0, %a], [%0, %a]
5:
  %phi2 = phi i32 [ %phi, %c], [%0, %4]
```


https://github.com/llvm/llvm-project/pull/151132


More information about the llvm-commits mailing list