Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit 0578a8e

Browse files
committed
[Devirtualization] Decorate vfunction load with invariant.load
Summary: This patch was introduced one year ago, but because my google account was disabled, I didn't get email with failing buildbot and I missed revert of this commit. There was small but in test regex. I am back. Reviewers: rsmith, rengolin Subscribers: nlewycky, rjmccall, cfe-commits Differential Revision: https://reviews.llvm.org/D26117 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@285497 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 4753b48 commit 0578a8e

File tree

2 files changed

+22
-2
lines changed

2 files changed

+22
-2
lines changed

Diff for: lib/CodeGen/ItaniumCXXABI.cpp

+16-1
Original file line numberDiff line numberDiff line change
@@ -1623,7 +1623,22 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
16231623

16241624
llvm::Value *VFuncPtr =
16251625
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn");
1626-
VFunc = CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
1626+
auto *VFuncLoad =
1627+
CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign());
1628+
1629+
// Add !invariant.load md to virtual function load to indicate that
1630+
// function didn't change inside vtable.
1631+
// It's safe to add it without -fstrict-vtable-pointers, but it would not
1632+
// help in devirtualization because it will only matter if we will have 2
1633+
// the same virtual function loads from the same vtable load, which won't
1634+
// happen without enabled devirtualization with -fstrict-vtable-pointers.
1635+
if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
1636+
CGM.getCodeGenOpts().StrictVTablePointers)
1637+
VFuncLoad->setMetadata(
1638+
llvm::LLVMContext::MD_invariant_load,
1639+
llvm::MDNode::get(CGM.getLLVMContext(),
1640+
llvm::ArrayRef<llvm::Metadata *>()));
1641+
VFunc = VFuncLoad;
16271642
}
16281643

16291644
CGCallee Callee(MethodDecl, VFunc);

Diff for: test/CodeGenCXX/virtual-function-calls.cpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s
2+
// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - -fstrict-vtable-pointers -O1 | FileCheck --check-prefix=CHECK-INVARIANT %s
23

34
// PR5021
45
namespace PR5021 {
@@ -42,10 +43,14 @@ namespace VirtualNoreturn {
4243
[[noreturn]] virtual void f();
4344
};
4445

45-
// CHECK: @_ZN15VirtualNoreturn1f
46+
// CHECK-LABEL: @_ZN15VirtualNoreturn1f
47+
// CHECK-INVARIANT-LABEL: define void @_ZN15VirtualNoreturn1f
4648
void f(A *p) {
4749
p->f();
4850
// CHECK: call {{.*}}void %{{[^#]*$}}
4951
// CHECK-NOT: unreachable
52+
// CHECK-INVARIANT: load {{.*}} !invariant.load ![[EMPTY_NODE:[0-9]+]]
5053
}
5154
}
55+
56+
// CHECK-INVARIANT: ![[EMPTY_NODE]] = !{}

0 commit comments

Comments
 (0)