Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash during inline call promotion due to VTablePtr not of PointerType #685

Open
NickLewisL3H opened this issue Mar 16, 2023 · 1 comment

Comments

@NickLewisL3H
Copy link

Crash when compiling Linux Kernel Library files: lkl/net/core/dev.c, lkl/net/core/sock_reuseport.c, lkl/drivers/net/virtio_net.c, lkl/net/ipv4/af_inet.c

Added debug msgs show:

Internal error when inlining callee: __dev_xmit_skb into __dev_queue_xmit: VTablePtr not of PointerType
Internal error when inlining callee: __dev_xmit_skb into __dev_queue_xmit: VTablePtr not of PointerType
Internal error when inlining callee: run_bpf into reuseport_select_sock: VTablePtr not of PointerType
Internal error when inlining callee: bpf_prog_run_xdp into receive_mergeable: VTablePtr not of PointerType
Internal error when inlining callee: bpf_prog_run_xdp into receive_small: VTablePtr not of PointerType
Internal error when inlining callee: call_gro_receive into inet_gro_receive: VTablePtr not of PointerType

All creduce to the same or very similar code:

void *a;
void b(void *c) { *(long *)c = a; }
struct d {
  int (*e)()
} f(struct d *c) {
  c->e();
}
void g() {
  struct d *h = ({
    typeof(0) *i = ({
      union {
        typeof(&g) j;
        char k[1]
      } l;
      b(l.k);
      l.j;
    });
    i;
  });
  f(h);
}
@NickLewisL3H
Copy link
Author

A workaround for the crash just forgoes call promotion in these cases:

--- a/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
+++ b/llvm/lib/Transforms/Utils/CallPromotionUtils.cpp
@@ -560,7 +560,10 @@ bool llvm::tryPromoteCall(CallBase &CB) {
       VTablePtrLoad, VTablePtrLoad->getParent(), BBI, 0, nullptr, nullptr);
   if (!VTablePtr)
     return false; // No vtable found.
-  APInt VTableOffsetGVBase(DL.getPointerAddrSizeInBits(VTablePtr->getType()),
+  Type *VTablePtrType = VTablePtr->getType();
+  if (!VTablePtrType->isPointerTy())
+    return false; //Not of pointer type.
+  APInt VTableOffsetGVBase(DL.getPointerAddrSizeInBits(VTablePtrType),
                            0);
   Value *VTableGVBase = VTablePtr->stripAndAccumulateConstantOffsets(
       DL, VTableOffsetGVBase, /* AllowNonInbounds */ true);

but this does not fully address the cause of the problem (in stripAndAccumulateConstantOffsets?)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant