r247725 - Decorating vptr load & stores with !invariant.group
Piotr Padlewski via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 15 14:46:55 PDT 2015
Author: prazek
Date: Tue Sep 15 16:46:55 2015
New Revision: 247725
URL: http://llvm.org/viewvc/llvm-project?rev=247725&view=rev
Log:
Decorating vptr load & stores with !invariant.group
Adding !invariant.group to vptr load/stores for devirtualization purposes.
For more goto:
http://lists.llvm.org/pipermail/cfe-dev/2015-July/044227.html
http://reviews.llvm.org/D12026
Added:
cfe/trunk/test/CodeGenCXX/invariant.group-for-vptrs.cpp
Modified:
cfe/trunk/lib/CodeGen/CGAtomic.cpp
cfe/trunk/lib/CodeGen/CGClass.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
Modified: cfe/trunk/lib/CodeGen/CGAtomic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGAtomic.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGAtomic.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGAtomic.cpp Tue Sep 15 16:46:55 2015
@@ -1246,7 +1246,7 @@ llvm::Value *AtomicInfo::EmitAtomicLoadO
if (IsVolatile)
Load->setVolatile(true);
if (LVal.getTBAAInfo())
- CGF.CGM.DecorateInstruction(Load, LVal.getTBAAInfo());
+ CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo());
return Load;
}
@@ -1769,7 +1769,7 @@ void CodeGenFunction::EmitAtomicStore(RV
if (IsVolatile)
store->setVolatile(true);
if (dest.getTBAAInfo())
- CGM.DecorateInstruction(store, dest.getTBAAInfo());
+ CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo());
return;
}
Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Tue Sep 15 16:46:55 2015
@@ -25,6 +25,7 @@
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/Metadata.h"
using namespace clang;
using namespace CodeGen;
@@ -2087,7 +2088,8 @@ void CodeGenFunction::EmitVTableAssumpti
ApplyNonVirtualAndVirtualOffset(*this, This, NonVirtualOffset, nullptr,
Vptr.VTableClass, Vptr.NearestVBase);
- llvm::Value *VPtrValue = GetVTablePtr(This, VTableGlobal->getType());
+ llvm::Value *VPtrValue =
+ GetVTablePtr(This, VTableGlobal->getType(), Vptr.VTableClass);
llvm::Value *Cmp =
Builder.CreateICmpEQ(VPtrValue, VTableGlobal, "cmp.vtables");
Builder.CreateAssumption(Cmp);
@@ -2306,7 +2308,10 @@ void CodeGenFunction::InitializeVTablePo
VTableAddressPoint = Builder.CreateBitCast(VTableAddressPoint, VTablePtrTy);
llvm::StoreInst *Store = Builder.CreateStore(VTableAddressPoint, VTableField);
- CGM.DecorateInstruction(Store, CGM.getTBAAInfoForVTablePtr());
+ CGM.DecorateInstructionWithTBAA(Store, CGM.getTBAAInfoForVTablePtr());
+ if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ CGM.getCodeGenOpts().StrictVTablePointers)
+ CGM.DecorateInstructionWithInvariantGroup(Store, Vptr.VTableClass);
}
CodeGenFunction::VPtrsVector
@@ -2393,10 +2398,16 @@ void CodeGenFunction::InitializeVTablePo
}
llvm::Value *CodeGenFunction::GetVTablePtr(Address This,
- llvm::Type *Ty) {
- Address VTablePtrSrc = Builder.CreateElementBitCast(This, Ty);
+ llvm::Type *VTableTy,
+ const CXXRecordDecl *RD) {
+ Address VTablePtrSrc = Builder.CreateElementBitCast(This, VTableTy);
llvm::Instruction *VTable = Builder.CreateLoad(VTablePtrSrc, "vtable");
- CGM.DecorateInstruction(VTable, CGM.getTBAAInfoForVTablePtr());
+ CGM.DecorateInstructionWithTBAA(VTable, CGM.getTBAAInfoForVTablePtr());
+
+ if (CGM.getCodeGenOpts().OptimizationLevel > 0 &&
+ CGM.getCodeGenOpts().StrictVTablePointers)
+ CGM.DecorateInstructionWithInvariantGroup(VTable, RD);
+
return VTable;
}
@@ -2481,7 +2492,8 @@ void CodeGenFunction::EmitVTablePtrCheck
}
llvm::Value *VTable =
- GetVTablePtr(Address(Derived, getPointerAlign()), Int8PtrTy);
+ GetVTablePtr(Address(Derived, getPointerAlign()), Int8PtrTy, ClassDecl);
+
EmitVTablePtrCheck(ClassDecl, VTable, TCK, Loc);
if (MayBeNull) {
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Sep 15 16:46:55 2015
@@ -1277,7 +1277,8 @@ llvm::Value *CodeGenFunction::EmitLoadOf
llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
TBAAOffset);
if (TBAAPath)
- CGM.DecorateInstruction(Load, TBAAPath, false/*ConvertTypeToTag*/);
+ CGM.DecorateInstructionWithTBAA(Load, TBAAPath,
+ false /*ConvertTypeToTag*/);
}
bool NeedsBoolCheck =
@@ -1391,7 +1392,8 @@ void CodeGenFunction::EmitStoreOfScalar(
llvm::MDNode *TBAAPath = CGM.getTBAAStructTagInfo(TBAABaseType, TBAAInfo,
TBAAOffset);
if (TBAAPath)
- CGM.DecorateInstruction(Store, TBAAPath, false/*ConvertTypeToTag*/);
+ CGM.DecorateInstructionWithTBAA(Store, TBAAPath,
+ false /*ConvertTypeToTag*/);
}
}
@@ -3115,7 +3117,7 @@ LValue CodeGenFunction::EmitLValueForFie
else
tbaa = CGM.getTBAAInfo(type);
if (tbaa)
- CGM.DecorateInstruction(load, tbaa);
+ CGM.DecorateInstructionWithTBAA(load, tbaa);
}
mayAlias = false;
Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Tue Sep 15 16:46:55 2015
@@ -258,7 +258,7 @@ RValue CodeGenFunction::EmitCXXMemberOrO
} else {
if (SanOpts.has(SanitizerKind::CFINVCall) &&
MD->getParent()->isDynamicClass()) {
- llvm::Value *VTable = GetVTablePtr(This, Int8PtrTy);
+ llvm::Value *VTable = GetVTablePtr(This, Int8PtrTy, MD->getParent());
EmitVTablePtrCheckForCall(MD, VTable, CFITCK_NVCall, CE->getLocStart());
}
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Sep 15 16:46:55 2015
@@ -1380,7 +1380,8 @@ public:
/// GetVTablePtr - Return the Value of the vtable pointer member pointed
/// to by This.
- llvm::Value *GetVTablePtr(Address This, llvm::Type *Ty);
+ llvm::Value *GetVTablePtr(Address This, llvm::Type *VTableTy,
+ const CXXRecordDecl *VTableClass);
enum CFITypeCheckKind {
CFITCK_VCall,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Sep 15 16:46:55 2015
@@ -507,9 +507,9 @@ llvm::MDNode *CodeGenModule::getTBAAStru
/// and struct-path aware TBAA, the tag has the same format:
/// base type, access type and offset.
/// When ConvertTypeToTag is true, we create a tag based on the scalar type.
-void CodeGenModule::DecorateInstruction(llvm::Instruction *Inst,
- llvm::MDNode *TBAAInfo,
- bool ConvertTypeToTag) {
+void CodeGenModule::DecorateInstructionWithTBAA(llvm::Instruction *Inst,
+ llvm::MDNode *TBAAInfo,
+ bool ConvertTypeToTag) {
if (ConvertTypeToTag && TBAA)
Inst->setMetadata(llvm::LLVMContext::MD_tbaa,
TBAA->getTBAAScalarTagInfo(TBAAInfo));
@@ -517,6 +517,16 @@ void CodeGenModule::DecorateInstruction(
Inst->setMetadata(llvm::LLVMContext::MD_tbaa, TBAAInfo);
}
+void CodeGenModule::DecorateInstructionWithInvariantGroup(
+ llvm::Instruction *I, const CXXRecordDecl *RD) {
+ llvm::Metadata *MD = CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ auto *MetaDataNode = dyn_cast<llvm::MDNode>(MD);
+ // Check if we have to wrap MDString in MDNode.
+ if (!MetaDataNode)
+ MetaDataNode = llvm::MDNode::get(getLLVMContext(), MD);
+ I->setMetadata("invariant.group", MetaDataNode);
+}
+
void CodeGenModule::Error(SourceLocation loc, StringRef message) {
unsigned diagID = getDiags().getCustomDiagID(DiagnosticsEngine::Error, "%0");
getDiags().Report(Context.getFullLoc(loc), diagID) << message;
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Sep 15 16:46:55 2015
@@ -658,9 +658,13 @@ public:
/// is the same as the type. For struct-path aware TBAA, the tag
/// is different from the type: base type, access type and offset.
/// When ConvertTypeToTag is true, we create a tag based on the scalar type.
- void DecorateInstruction(llvm::Instruction *Inst,
- llvm::MDNode *TBAAInfo,
- bool ConvertTypeToTag = true);
+ void DecorateInstructionWithTBAA(llvm::Instruction *Inst,
+ llvm::MDNode *TBAAInfo,
+ bool ConvertTypeToTag = true);
+
+ /// Adds !invariant.barrier !tag to instruction
+ void DecorateInstructionWithInvariantGroup(llvm::Instruction *I,
+ const CXXRecordDecl *RD);
/// Emit the given number of characters as a value of type size_t.
llvm::ConstantInt *getSize(CharUnits numChars);
Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Sep 15 16:46:55 2015
@@ -584,7 +584,7 @@ llvm::Value *ItaniumCXXABI::EmitLoadOfMe
CGF.CGM.getDynamicOffsetAlignment(ThisAddr.getAlignment(), RD,
CGF.getPointerAlign());
llvm::Value *VTable =
- CGF.GetVTablePtr(Address(This, VTablePtrAlign), VTableTy);
+ CGF.GetVTablePtr(Address(This, VTablePtrAlign), VTableTy, RD);
// Apply the offset.
llvm::Value *VTableOffset = FnAsInt;
@@ -1012,7 +1012,10 @@ void ItaniumCXXABI::emitVirtualObjectDel
// to pass to the deallocation function.
// Grab the vtable pointer as an intptr_t*.
- llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo());
+ auto *ClassDecl =
+ cast<CXXRecordDecl>(ElementType->getAs<RecordType>()->getDecl());
+ llvm::Value *VTable =
+ CGF.GetVTablePtr(Ptr, CGF.IntPtrTy->getPointerTo(), ClassDecl);
// Track back to entry -2 and pull out the offset there.
llvm::Value *OffsetPtr = CGF.Builder.CreateConstInBoundsGEP1_64(
@@ -1211,8 +1214,10 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(C
QualType SrcRecordTy,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) {
+ auto *ClassDecl =
+ cast<CXXRecordDecl>(SrcRecordTy->getAs<RecordType>()->getDecl());
llvm::Value *Value =
- CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo());
+ CGF.GetVTablePtr(ThisPtr, StdTypeInfoPtrTy->getPointerTo(), ClassDecl);
// Load the type info.
Value = CGF.Builder.CreateConstInBoundsGEP1_64(Value, -1ULL);
@@ -1275,8 +1280,11 @@ llvm::Value *ItaniumCXXABI::EmitDynamicC
CGF.ConvertType(CGF.getContext().getPointerDiffType());
llvm::Type *DestLTy = CGF.ConvertType(DestTy);
+ auto *ClassDecl =
+ cast<CXXRecordDecl>(SrcRecordTy->getAs<RecordType>()->getDecl());
// Get the vtable pointer.
- llvm::Value *VTable = CGF.GetVTablePtr(ThisAddr, PtrDiffLTy->getPointerTo());
+ llvm::Value *VTable = CGF.GetVTablePtr(ThisAddr, PtrDiffLTy->getPointerTo(),
+ ClassDecl);
// Get the offset-to-top from the vtable.
llvm::Value *OffsetToTop =
@@ -1305,7 +1313,7 @@ ItaniumCXXABI::GetVirtualBaseClassOffset
Address This,
const CXXRecordDecl *ClassDecl,
const CXXRecordDecl *BaseClassDecl) {
- llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy);
+ llvm::Value *VTablePtr = CGF.GetVTablePtr(This, CGM.Int8PtrTy, ClassDecl);
CharUnits VBaseOffsetOffset =
CGM.getItaniumVTableContext().getVirtualBaseOffsetOffset(ClassDecl,
BaseClassDecl);
@@ -1591,10 +1599,11 @@ llvm::Value *ItaniumCXXABI::getVirtualFu
SourceLocation Loc) {
GD = GD.getCanonicalDecl();
Ty = Ty->getPointerTo()->getPointerTo();
- llvm::Value *VTable = CGF.GetVTablePtr(This, Ty);
+ auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
+ llvm::Value *VTable = CGF.GetVTablePtr(This, Ty, MethodDecl->getParent());
if (CGF.SanOpts.has(SanitizerKind::CFIVCall))
- CGF.EmitVTablePtrCheckForCall(cast<CXXMethodDecl>(GD.getDecl()), VTable,
+ CGF.EmitVTablePtrCheckForCall(MethodDecl, VTable,
CodeGenFunction::CFITCK_VCall, Loc);
uint64_t VTableIndex = CGM.getItaniumVTableContext().getMethodVTableIndex(GD);
Modified: cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp?rev=247725&r1=247724&r2=247725&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/MicrosoftCXXABI.cpp Tue Sep 15 16:46:55 2015
@@ -1831,7 +1831,9 @@ llvm::Value *MicrosoftCXXABI::getVirtual
Ty = Ty->getPointerTo()->getPointerTo();
Address VPtr =
adjustThisArgumentForVirtualFunctionCall(CGF, GD, This, true);
- llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty);
+
+ auto *MethodDecl = cast<CXXMethodDecl>(GD.getDecl());
+ llvm::Value *VTable = CGF.GetVTablePtr(VPtr, Ty, MethodDecl->getParent());
MicrosoftVTableContext::MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
@@ -1958,7 +1960,8 @@ llvm::Function *MicrosoftCXXABI::EmitVir
// Load the vfptr and then callee from the vftable. The callee should have
// adjusted 'this' so that the vfptr is at offset zero.
llvm::Value *VTable = CGF.GetVTablePtr(
- getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo());
+ getThisAddress(CGF), ThunkTy->getPointerTo()->getPointerTo(), MD->getParent());
+
llvm::Value *VFuncPtr =
CGF.Builder.CreateConstInBoundsGEP1_64(VTable, ML.Index, "vfn");
llvm::Value *Callee =
Added: cfe/trunk/test/CodeGenCXX/invariant.group-for-vptrs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/invariant.group-for-vptrs.cpp?rev=247725&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/invariant.group-for-vptrs.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/invariant.group-for-vptrs.cpp Tue Sep 15 16:46:55 2015
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm %s -fstrict-vtable-pointers -O1 -o - -disable-llvm-optzns | FileCheck %s
+
+struct A {
+ virtual void foo();
+};
+
+struct D : A {
+ void foo();
+};
+
+// CHECK-LABEL: define void @_Z21testExternallyVisiblev()
+void testExternallyVisible() {
+ A *a = new A;
+
+ // CHECK: load {{.*}} !invariant.group ![[A_MD:[0-9]+]]
+ a->foo();
+
+ D *d = new D;
+ // CHECK: call void @_ZN1DC1Ev(
+ // CHECK: load {{.*}} !invariant.group ![[D_MD:[0-9]+]]
+ d->foo();
+ A *a2 = d;
+ // CHECK: load {{.*}} !invariant.group ![[A_MD]]
+ a2->foo();
+}
+// CHECK-LABEL: }
+
+namespace {
+
+struct B {
+ virtual void bar();
+};
+
+struct C : B {
+ void bar();
+};
+
+}
+
+// CHECK-LABEL: define void @_Z21testInternallyVisibleb(
+void testInternallyVisible(bool p) {
+ B *b = new B;
+ // CHECK: = load {{.*}}, !invariant.group ![[B_MD:[0-9]+]]
+ b->bar();
+
+ // CHECK: call void @_ZN12_GLOBAL__N_11CC1Ev(
+ C *c = new C;
+ // CHECK: = load {{.*}}, !invariant.group ![[C_MD:[0-9]+]]
+ c->bar();
+}
+
+// Checking A::A()
+// CHECK-LABEL: define linkonce_odr void @_ZN1AC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[A_MD]]
+// CHECK-LABEL: }
+
+// Checking D::D()
+// CHECK-LABEL: define linkonce_odr void @_ZN1DC2Ev(
+
+// CHECK: call void @_ZN1AC2Ev(%struct.A*
+// CHECK: = call i8* @llvm.invariant.group.barrier(i8*
+// CHECK: store {{.*}} !invariant.group ![[D_MD]]
+
+// Checking B::B()
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_11BC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[B_MD]]
+
+// Checking C::C()
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_11CC2Ev(
+// CHECK: store {{.*}}, !invariant.group ![[C_MD]]
+
+// CHECK: ![[A_MD]] = !{!"_ZTS1A"}
+// CHECK: ![[D_MD]] = !{!"_ZTS1D"}
+// CHECK: ![[B_MD]] = distinct !{}
+// CHECK: ![[C_MD]] = distinct !{}
More information about the cfe-commits
mailing list