aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CGClass.cpp
diff options
context:
space:
mode:
authorArthur Eubanks <aeubanks@google.com>2022-06-30 15:18:04 -0700
committerArthur Eubanks <aeubanks@google.com>2022-07-26 08:01:08 -0700
commit2eade1dba4a8d6e1c6867e9127bcd88cf4e55976 (patch)
tree080ccfec588a3231d14022bc922f5c05e9a11adb /clang/lib/CodeGen/CGClass.cpp
parente43621b09c9741d2e3a8a3d8ed216699af5ff8ba (diff)
downloadllvm-2eade1dba4a8d6e1c6867e9127bcd88cf4e55976.zip
llvm-2eade1dba4a8d6e1c6867e9127bcd88cf4e55976.tar.gz
llvm-2eade1dba4a8d6e1c6867e9127bcd88cf4e55976.tar.bz2
[WPD] Use new llvm.public.type.test intrinsic for potentially publicly visible classes
Turning on opaque pointers has uncovered an issue with WPD where we currently pattern match away `assume(type.test)` in WPD so that a later LTT doesn't resolve the type test to undef and introduce an `assume(false)`. The pattern matching can fail in cases where we transform two `assume(type.test)`s into `assume(phi(type.test.1, type.test.2))`. Currently we create `assume(type.test)` for all virtual calls that might be devirtualized. This is to support `-Wl,--lto-whole-program-visibility`. To prevent this, all virtual calls that may not be in the same LTO module instead use a new `llvm.public.type.test` intrinsic in place of the `llvm.type.test`. Then when we know if `-Wl,--lto-whole-program-visibility` is passed or not, we can either replace all `llvm.public.type.test` with `llvm.type.test`, or replace all `llvm.public.type.test` with `true`. This prevents WPD from trying to pattern match away `assume(type.test)` for public virtual calls when failing the pattern matching will result in miscompiles. Reviewed By: tejohnson Differential Revision: https://reviews.llvm.org/D128955
Diffstat (limited to 'clang/lib/CodeGen/CGClass.cpp')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index cde3171..c6696c4 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2698,15 +2698,21 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
// Don't insert type test assumes if we are forcing public
// visibility.
!CGM.AlwaysHasLTOVisibilityPublic(RD)) {
- llvm::Metadata *MD =
- CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ QualType Ty = QualType(RD->getTypeForDecl(), 0);
+ llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(Ty);
llvm::Value *TypeId =
llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
llvm::Value *CastedVTable = Builder.CreateBitCast(VTable, Int8PtrTy);
+ // If we already know that the call has hidden LTO visibility, emit
+ // @llvm.type.test(). Otherwise emit @llvm.public.type.test(), which WPD
+ // will convert to @llvm.type.test() if we assert at link time that we have
+ // whole program visibility.
+ llvm::Intrinsic::ID IID = CGM.HasHiddenLTOVisibility(RD)
+ ? llvm::Intrinsic::type_test
+ : llvm::Intrinsic::public_type_test;
llvm::Value *TypeTest =
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::type_test),
- {CastedVTable, TypeId});
+ Builder.CreateCall(CGM.getIntrinsic(IID), {CastedVTable, TypeId});
Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::assume), TypeTest);
}
}