[llvm] [llubi] Add basic support for icmp, terminators and function calls (PR #181393)

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Sat Feb 14 01:15:52 PST 2026


================
@@ -219,6 +254,188 @@ class InstExecutor : public InstVisitor<InstExecutor, void> {
     Status &= Handler.onInstructionExecuted(RI, None);
   }
 
+  void visitBranchInst(BranchInst &BI) {
+    if (BI.isConditional()) {
+      switch (getValue(BI.getCondition()).asBoolean()) {
+      case BooleanKind::True:
+        jumpTo(BI, BI.getSuccessor(0));
+        return;
+      case BooleanKind::False:
+        jumpTo(BI, BI.getSuccessor(1));
+        return;
+      case BooleanKind::Poison:
+        reportImmediateUB("Branch on poison condition.");
+        return;
+      }
+    }
+    jumpTo(BI, BI.getSuccessor(0));
+  }
+
+  void visitSwitchInst(SwitchInst &SI) {
+    auto &Cond = getValue(SI.getCondition());
+    if (Cond.isPoison()) {
+      reportImmediateUB("Switch on poison condition.");
+      return;
+    }
+    for (auto &Case : SI.cases()) {
+      if (Case.getCaseValue()->getValue() == Cond.asInteger()) {
+        jumpTo(SI, Case.getCaseSuccessor());
+        return;
+      }
+    }
+    jumpTo(SI, SI.getDefaultDest());
+  }
+
+  void visitUnreachableInst(UnreachableInst &) {
+    reportImmediateUB("Unreachable code.");
+  }
+
+  void visitCallBrInst(CallBrInst &CI) {
+    if (isNoopInlineAsm(CI.getCalledOperand(), CI.getType())) {
+      jumpTo(CI, CI.getDefaultDest());
+      return;
+    }
+
+    Handler.onUnrecognizedInstruction(CI);
+    Status = false;
+  }
+
+  void visitIndirectBrInst(IndirectBrInst &IBI) {
+    auto &Target = getValue(IBI.getAddress());
+    if (Target.isPoison()) {
+      reportImmediateUB("Indirect branch on poison.");
+      return;
+    }
+    if (BasicBlock *DestBB = Ctx.getTargetBlock(Target.asPointer())) {
+      if (any_of(IBI.successors(),
+                 [DestBB](BasicBlock *Succ) { return Succ == DestBB; }))
+        jumpTo(IBI, DestBB);
+      else
+        reportImmediateUB("Indirect branch on unlisted target BB.");
+
+      return;
+    }
+    reportImmediateUB("Indirect branch on invalid target BB.");
+  }
+
+  void returnFromCallee() {
+    // TODO: handle retval attributes (Attributes from known callee should be
+    // applied if available).
+    // TODO: handle metadata
+    auto &CB = cast<CallBase>(*CurrentFrame->PC);
+    CurrentFrame->CalleeArgs.clear();
+    AnyValue &RetVal = CurrentFrame->CalleeRetVal;
+    setResult(CB, std::move(RetVal));
+
+    if (auto *II = dyn_cast<InvokeInst>(&CB))
+      jumpTo(*II, II->getNormalDest());
+    else if (CurrentFrame->State == FrameState::Pending)
+      ++CurrentFrame->PC;
+  }
+
+  AnyValue callIntrinsic(CallBase &CB) {
+    Intrinsic::ID IID = CB.getIntrinsicID();
+    switch (IID) {
+    case Intrinsic::assume:
+      switch (getValue(CB.getArgOperand(0)).asBoolean()) {
+      case BooleanKind::True:
+        break;
+      case BooleanKind::False:
+      case BooleanKind::Poison:
+        reportImmediateUB("Assume on false or poison condition.");
----------------
nikic wrote:

Not tested.

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


More information about the llvm-commits mailing list