[llvm-dev] RFC: Emitting empty invariant group for vtable loads

Richard Smith via llvm-dev llvm-dev at lists.llvm.org
Mon Jan 30 09:38:05 PST 2017

On 20 Jan 2017 8:07 am, "Piotr Padlewski" <piotr.padlewski at gmail.com> wrote:

Hi all,

I would like to propose a new way clang would decorate vtable loads in
order to handle devirtualization better.

I've added *llvm-dev* also, because this can start a discussion about
changing invariant.group to just invariant.

PDF version of this RFC can be found here:



Initial old design:


My talk from LLVM Dev Meeting


The problem

Clang with -fstrict-vtable-pointers decorates vtable loads with metadata
corresponding to mangled pointer type name like:

void g(A& a){

define void @_Z1gR1A(%struct.A* dereferenceable(8) %a) local_unnamed_addr #0
 %0 = bitcast %struct.A* %a to void (%struct.A*)***
 %vtable = load void (%struct.A*)**, void (%struct.A*)*** %0,
!invariant.group !7
 %1 = load void (%struct.A*)*, void (%struct.A*)** %vtable
 tail call void %1(%struct.A* nonnull %a)
 ret void

!7 = !{!"_ZTS1A"}

This works well if the pointer type doesn’t change, but when it does,
devirtualization might not happen like here:

struct A {
   virtual void foo();
struct B : A{
   virtual void foo();
void g(A& a){
void clobber(A&);
void f() {
     B b;

The other problem is that when we combine 2 instructions with different
invariant.group metadata, then we pick one of them, because for now we can
have only single !invariant.group metadata.

The solution

I had some initial ideas how it can be solved, like


   introducing multi invariant groups

   having sub invariant groups - like inheritance, so we could figure out
   that one group is subgroup of another

   decorating all loads with base pointer MD (doesn’t work with multiple

The original idea was that the metadata would indicate the class that
introduced the vptr; that seems like it should work ok with multiple
inheritance. Is there a problem with that approach? (We may still be able
to remove it entirely, which could still be preferable.)

I consulted my ideas with Krzysztof Pszeniczny, and he proposed something
much simpler: we can decorate every invariant.group md with empty metadata.

This should work because the lifetime of the object is strictly defined by

If this holds, we can start discussion about if it makes sense to keep
invariant groups, and instead have just “invariant”, that would be
equivalent to having invariant.group with the same metadata.

Do you have some thoughts about this approach? I don’t have a mathematical
proof, but I am confident that it should be valid.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170130/25b92c10/attachment.html>

More information about the llvm-dev mailing list