[llvm-dev] Call via Vtable

Santanu Das via llvm-dev llvm-dev at lists.llvm.org
Sun Jul 11 23:00:40 PDT 2021


Hello community members,

I was experimenting to see whether LLVM is able to devirtualize calls via vtable. I have this particular example:

========
class Foo {
public:
  virtual int foo() const = 0;
  int baz() const { return foo(); }
};

class Bar : public Foo {
public:
  int foo() const override final { return 0xdeadbeef; }
};

int fred(Bar &x) {
  return x.baz();
}
========

As we can see, there is a call to Bar::foo(), via  Foo::baz(), which returns a constant.
The Bar::foo() function has final specifier, hence this implementation cannot be overridden by any child class.  In this case, the compiler should be able to call Bar::foo() directly instead of calling via vtable, and then should be able to inline the const value.

When I compile with LLVM main branch, I see this piece of code being generated below. It makes a call to the function via vtable entry.

_Z4fredR3Bar:
movq    (%rdi), %rax
jmpq    *(%rax)


When I compile with GCC, I see that it is able to correctly identify that it should call Bar::foo() directly and successfully inlines the const value.

_Z4fredR3Bar:
movq    (%rdi), %rax
movq    (%rax), %rax
cmpq    $_ZNK3Bar3fooEv, %rax
jne     .L5
movl    $-559038737, %eax
ret


Should LLVM be optimizing this call, or am I missing something?

-
Santanu Das
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210712/e7d58940/attachment.html>


More information about the llvm-dev mailing list