[llvm-bugs] [Bug 28724] New: -fstrict-vtable-pointers does not seem to optimise vtable access as much as I would expect.

via llvm-bugs llvm-bugs at lists.llvm.org
Tue Jul 26 13:14:54 PDT 2016


https://llvm.org/bugs/show_bug.cgi?id=28724

            Bug ID: 28724
           Summary: -fstrict-vtable-pointers does not seem to optimise
                    vtable access as much as I would expect.
           Product: clang
           Version: 2.6
          Hardware: PC
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++
          Assignee: unassignedclangbugs at nondot.org
          Reporter: oliver at apple.com
                CC: dgregor at apple.com, llvm-bugs at lists.llvm.org
    Classification: Unclassified

Created attachment 16811
  --> https://llvm.org/bugs/attachment.cgi?id=16811&action=edit
example code

If I take the attached example and compile with:
clang++ -Os -std=c++11  -fstrict-vtable-pointers example.cpp -emit-llvm -S -o -

The output for the main for-loop is
for.body:                                         ; preds = %for.body, %entry
  %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  %vtable = load void (%class.Bar*)**, void (%class.Bar*)*** %0, align 8,
!invariant.group !8
  %1 = load void (%class.Bar*)*, void (%class.Bar*)** %vtable, align 8
  tail call void %1(%class.Bar* nonnull %call)
  %vfn2 = getelementptr inbounds void (%class.Bar*)*, void (%class.Bar*)**
%vtable, i64 1
  %2 = load void (%class.Bar*)*, void (%class.Bar*)** %vfn2, align 8
  tail call void %2(%class.Bar* nonnull %call)
  %inc = add nuw nsw i32 %i.07, 1
  %exitcond = icmp eq i32 %inc, 100
  br i1 %exitcond, label %for.cond.cleanup, label %for.body
}

My interpretation of the -fstrict-vtable-pointers flag is that we're deciding
that the an object's vtable pointer cannot be mutated. If that is the case then
in the above IR %vtable should be a loop invariant as %0 is also invariant.
That means the assignment to %vtable should be hoistable via LICM.

Once %vtable is hoisted, then %1 and %2 should also be hoisted, as vtables are
constant under my understanding of -fstrict-vtable-pointers.

So I think we should be able to produce IR that looks something like:

%vtable = load void (%class.Bar*)**, void (%class.Bar*)*** %0, align 8,
!invariant.group !8
%1 = load void (%class.Bar*)*, void (%class.Bar*)** %vtable, align 8
%vfn2 = getelementptr inbounds void (%class.Bar*)*, void (%class.Bar*)**
%vtable, i64 1
%2 = load void (%class.Bar*)*, void (%class.Bar*)** %vfn2, align 8

for.body:                                         ; preds = %for.body, %entry
  %i.07 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
  tail call void %1(%class.Bar* nonnull %call)
  tail call void %2(%class.Bar* nonnull %call)
  %inc = add nuw nsw i32 %i.07, 1
  %exitcond = icmp eq i32 %inc, 100
  br i1 %exitcond, label %for.cond.cleanup, label %for.body
}

This IR is a rough approximation via the wonders of cut/paste, so be gentle
with errors :D

I'm unsure how common code would benefit, but this does go against my intuition
of expected behaviour.

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20160726/4486c817/attachment-0001.html>


More information about the llvm-bugs mailing list