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

Piotr Padlewski via llvm-dev llvm-dev at lists.llvm.org
Fri Jan 20 08:07:04 PST 2017

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

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/20170120/70e62e86/attachment.html>

More information about the llvm-dev mailing list