From 77cc962bce121cd270afdcf7238ae7566853a37a Mon Sep 17 00:00:00 2001 From: Piotr Padlewski Date: Sat, 29 Oct 2016 15:28:30 +0000 Subject: [PATCH] [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 llvm-svn: 285497 --- clang/lib/CodeGen/ItaniumCXXABI.cpp | 17 ++++++++++++++++- clang/test/CodeGenCXX/virtual-function-calls.cpp | 7 ++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp index b8dec54..29261fd 100644 --- a/clang/lib/CodeGen/ItaniumCXXABI.cpp +++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp @@ -1623,7 +1623,22 @@ CGCallee ItaniumCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF, llvm::Value *VFuncPtr = CGF.Builder.CreateConstInBoundsGEP1_64(VTable, VTableIndex, "vfn"); - VFunc = CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); + auto *VFuncLoad = + CGF.Builder.CreateAlignedLoad(VFuncPtr, CGF.getPointerAlign()); + + // Add !invariant.load md to virtual function load to indicate that + // function didn't change inside vtable. + // It's safe to add it without -fstrict-vtable-pointers, but it would not + // help in devirtualization because it will only matter if we will have 2 + // the same virtual function loads from the same vtable load, which won't + // happen without enabled devirtualization with -fstrict-vtable-pointers. + if (CGM.getCodeGenOpts().OptimizationLevel > 0 && + CGM.getCodeGenOpts().StrictVTablePointers) + VFuncLoad->setMetadata( + llvm::LLVMContext::MD_invariant_load, + llvm::MDNode::get(CGM.getLLVMContext(), + llvm::ArrayRef())); + VFunc = VFuncLoad; } CGCallee Callee(MethodDecl, VFunc); diff --git a/clang/test/CodeGenCXX/virtual-function-calls.cpp b/clang/test/CodeGenCXX/virtual-function-calls.cpp index 0a6fc6b..22944d9 100644 --- a/clang/test/CodeGenCXX/virtual-function-calls.cpp +++ b/clang/test/CodeGenCXX/virtual-function-calls.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - -fstrict-vtable-pointers -O1 | FileCheck --check-prefix=CHECK-INVARIANT %s // PR5021 namespace PR5021 { @@ -42,10 +43,14 @@ namespace VirtualNoreturn { [[noreturn]] virtual void f(); }; - // CHECK: @_ZN15VirtualNoreturn1f + // CHECK-LABEL: @_ZN15VirtualNoreturn1f + // CHECK-INVARIANT-LABEL: define void @_ZN15VirtualNoreturn1f void f(A *p) { p->f(); // CHECK: call {{.*}}void %{{[^#]*$}} // CHECK-NOT: unreachable + // CHECK-INVARIANT: load {{.*}} !invariant.load ![[EMPTY_NODE:[0-9]+]] } } + +// CHECK-INVARIANT: ![[EMPTY_NODE]] = !{} -- 2.7.4