Index: lib/CodeGen/CGClass.cpp =================================================================== --- lib/CodeGen/CGClass.cpp +++ lib/CodeGen/CGClass.cpp @@ -1375,13 +1375,14 @@ assert(BaseCtorContinueBB); } - bool BaseVPtrsInitialized = false; + llvm::Value *const OldThis = CXXThisValue; // Virtual base initializers first. for (; B != E && (*B)->isBaseInitializer() && (*B)->isBaseVirtual(); B++) { - CXXCtorInitializer *BaseInit = *B; + if (CGM.getCodeGenOpts().StrictVTablePointers && + CGM.getCodeGenOpts().OptimizationLevel > 0 && + isInitializerOfDynamicClass(*B)) + CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis()); EmitBaseInitializer(*this, ClassDecl, *B, CtorType); - BaseVPtrsInitialized |= BaseInitializerUsesThis(getContext(), - BaseInit->getInit()); } if (BaseCtorContinueBB) { @@ -1393,15 +1394,15 @@ // Then, non-virtual base initializers. for (; B != E && (*B)->isBaseInitializer(); B++) { assert(!(*B)->isBaseVirtual()); + + if (CGM.getCodeGenOpts().StrictVTablePointers && + CGM.getCodeGenOpts().OptimizationLevel > 0 && + isInitializerOfDynamicClass(*B)) + CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis()); EmitBaseInitializer(*this, ClassDecl, *B, CtorType); - BaseVPtrsInitialized |= isInitializerOfDynamicClass(*B); } - // Pointer to this requires to be passed through invariant.group.barrier - // only if we've initialized any base vptrs. - if (CGM.getCodeGenOpts().StrictVTablePointers && - CGM.getCodeGenOpts().OptimizationLevel > 0 && BaseVPtrsInitialized) - CXXThisValue = Builder.CreateInvariantGroupBarrier(LoadCXXThis()); + CXXThisValue = OldThis; InitializeVTablePointers(ClassDecl); Index: test/CodeGenCXX/invariant.group-for-vptrs.cpp =================================================================== --- test/CodeGenCXX/invariant.group-for-vptrs.cpp +++ test/CodeGenCXX/invariant.group-for-vptrs.cpp @@ -56,9 +56,8 @@ // 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: call void @_ZN1AC2Ev(%struct.A* // CHECK: store {{.*}} !invariant.group ![[D_MD]] // Checking B::B() Index: test/CodeGenCXX/strict-vtable-pointers.cpp =================================================================== --- test/CodeGenCXX/strict-vtable-pointers.cpp +++ test/CodeGenCXX/strict-vtable-pointers.cpp @@ -136,26 +136,43 @@ struct DynamicDerived; + // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev( -// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev( -// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0:.*]] to i8* +// CHECK-CTORS: %[[THIS0:.*]] = load %[[DynamicDerived:.*]]*, %[[DynamicDerived]]** {{.*}} +// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[DynamicDerived:.*]]* %[[THIS0]] to i8* // CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1:.*]]) -// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2:.*]] to %[[DynamicDerived]]* -// CHECK-CTORS: %[[THIS4:.*]] = bitcast %struct.DynamicDerived* %[[THIS3:.*]] to i32 (...)*** -// CHECK-CTORS: store {{.*}} %[[THIS4:.*]] +// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[DynamicDerived]]* +// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[DynamicDerived]]* %2 to %[[DynamicBase:.*]]* +// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[DynamicBase]]* %[[THIS4]]) + +// CHECK-CTORS: %[[THIS5:.*]] = bitcast %struct.DynamicDerived* %[[THIS0]] to i32 (...)*** +// CHECK-CTORS: store {{.*}} %[[THIS5]] // CHECK-CTORS-LABEL: } struct DynamicDerivedMultiple; -// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev -// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev( +// CHECK-CTORS-LABEL: define linkonce_odr void @_ZN22DynamicDerivedMultipleC2Ev( + +// CHECK-CTORS: %[[THIS0:.*]] = load %[[CLASS:.*]]*, %[[CLASS]]** {{.*}} +// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0]] to i8* +// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1]]) +// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2]] to %[[CLASS]]* +// CHECK-CTORS: %[[THIS4:.*]] = bitcast %[[CLASS]]* %[[THIS3]] to %[[BASE_CLASS:.*]]* +// CHECK-CTORS: call void @_ZN12DynamicBase1C2Ev(%[[BASE_CLASS]]* %[[THIS4]]) + +// CHECK-CTORS: call i8* @llvm.invariant.group.barrier( + +// CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev( // CHECK-CTORS-NOT: @llvm.invariant.group.barrier -// CHECK-CTORS-LABEL: call void @_ZN12DynamicBase2C2Ev( -// CHECK-CTORS: %[[THIS1:.*]] = bitcast %[[CLASS:.*]]* %[[THIS0:.*]] to i8* -// CHECK-CTORS: %[[THIS2:.*]] = call i8* @llvm.invariant.group.barrier(i8* %[[THIS1:.*]]) -// CHECK-CTORS: %[[THIS3:.*]] = bitcast i8* %[[THIS2:.*]] to %[[CLASS]]* -// CHECK-CTORS-NOT: invariant.group.barrier -// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 2) -// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 6) + + +// CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)*** +// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 2) {{.*}} %[[THIS10]] +// CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8* +// CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16 +// CHECK-CTORS: %[[THIS12:.*]] = bitcast i8* %[[THIS_ADD]] to i32 (...)*** + + +// CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i64 0, i64 6) {{.*}} %[[THIS12]] // CHECK-CTORS-LABEL: } struct DynamicFromStatic;