[llvm] [BPF] Support Jump Table (PR #149715)

via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 22 22:33:40 PDT 2025


yonghong-song wrote:

> > Two observations for test case with two jump tables ([link](https://gist.github.com/eddyz87/ff1b9895df194cd8934d2a8728e5ffd7)).
> > ### Jump table element size
> > Array indices are computed for element size of 8:
> > ```
> >         r3 = (s32)r2
> >         r3 <<= 3
> >         r2 = BPF.JT.0.0 ll
> >         r2 += r3
> > ```
[...]
> > ### Leftover globals
> > Global variables for arrays `jt1` and `jt2` are emitted:
> > ```
> > .L__const.foo.jt1:
> >         .quad   .Ltmp0
> >         .quad   .Ltmp1
> >         .size   .L__const.foo.jt1, 16
> > 
> >         .type   .L__const.foo.jt2, at object       # @__const.foo.jt2
> >         .p2align        3, 0x0
> > ```
> > We should probably clean these (at-least if there are no references to these symbols in the final code).

Fixed the element size issue. The element size is 8 now.

For cleaning up globals like __const.foo.jt{1,2}. I tried to remove them during finalization like below:
```
diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
index 03f7d8d035dd..b1a24ec9a788 100644
--- a/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
+++ b/llvm/lib/Target/BPF/BPFAsmPrinter.cpp
@@ -133,6 +133,39 @@ void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
   EmitToStreamer(*OutStreamer, TmpInst);
 }
 
+bool BPFAsmPrinter::doFinalization(Module &M) {
+  // Remove computed goto globals like
+  // @__const.foo.jt1 = private unnamed_addr constant [2 x ptr]
+  //     [ptr blockaddress(@foo, %l1), ptr blockaddress(@foo, %l2)], align 8
+  // These globals have been replaced with a jumptable label.
+
+  std::vector<GlobalVariable *> Targets;
+  for (GlobalVariable &Global : M.globals()) {
+    if (Global.getLinkage() != GlobalValue::PrivateLinkage)
+      continue;
+    if (!Global.isConstant() || !Global.hasInitializer())
+      continue;
+
+    Constant *CV = dyn_cast<Constant>(Global.getInitializer());
+    if (!CV)
+      continue;
+    ConstantArray *CA = dyn_cast<ConstantArray>(CV);
+    if (!CA)
+      continue;
+
+    for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
+      if (!dyn_cast<BlockAddress>(CA->getOperand(i)))
+        continue;
+    }
+    Targets.push_back(&Global);
+  }
+
+  for (GlobalVariable *GV : Targets)
+    GV->eraseFromParent();
+
+  return AsmPrinter::doFinalization(M);
+}
+
 MCSymbol *BPFAsmPrinter::getJTPublicSymbol(unsigned JTI) {
   SmallString<60> Name;
   raw_svector_ostream(Name)
diff --git a/llvm/lib/Target/BPF/BPFAsmPrinter.h b/llvm/lib/Target/BPF/BPFAsmPrinter.h
index 2e6e8a7d491f..e5731bd8e3b4 100644
--- a/llvm/lib/Target/BPF/BPFAsmPrinter.h
+++ b/llvm/lib/Target/BPF/BPFAsmPrinter.h
@@ -29,6 +29,7 @@ public:
                              const char *ExtraCode, raw_ostream &O) override;
 
   void emitInstruction(const MachineInstr *MI) override;
+  bool doFinalization(Module &M) override;
   MCSymbol *getJTPublicSymbol(unsigned JTI);
   MCSymbol *lowerBlockAddress(const BlockAddress *BA);
   MCSymbol *lowerGlobalValue(const GlobalValue *GVal);
```

But unfortunately, I hit a build failure with the above
```
    While deleting: ptr %__const.foo.jt1
    Use still stuck around after Def is destroyed:  %arrayidx = getelementptr inbounds [2 x ptr], ptr @__const.fo
    o.jt1, i64 0, i64 %idxprom
    Uses remain when a value is destroyed!
    UNREACHABLE executed at /home/yhs/work/yhs/llvm-project/llvm/lib/IR/Value.cpp:102!
    PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, p
    reprocessed source, and associated run script.
...
```
Clearly even at this stage, the llvm itself still kept lots of references and won't be able to remove them easily.

The good news are these symbols with name '.L_const.foo.jt{0,1}' and won't show up in the symbol table. The only side effect is it takes some space in .rodata section and I think it should be fine.

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


More information about the llvm-commits mailing list