diff options
author | Vedant Kumar <vsk@apple.com> | 2017-04-26 02:17:21 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-04-26 02:17:21 +0000 |
commit | e859ebbd0619c901f2f845c54ce484f5afdd8ab6 (patch) | |
tree | 3b553163aacada92afca4d47b3c9666bfc65c26d /clang/lib/CodeGen/CGExpr.cpp | |
parent | 0827b7ff3ecbe9d826ecc8fadb52717e373200e5 (diff) | |
download | bcm5719-llvm-e859ebbd0619c901f2f845c54ce484f5afdd8ab6.tar.gz bcm5719-llvm-e859ebbd0619c901f2f845c54ce484f5afdd8ab6.zip |
[ubsan] Skip alignment checks on allocas with known alignment
It's possible to determine the alignment of an alloca at compile-time.
Use this information to skip emitting some runtime alignment checks.
Testing: check-clang, check-ubsan.
This significantly reduces the amount of alignment checks we emit when
compiling X86ISelLowering.cpp. Here are the numbers from patched/unpatched
clangs based on r301361.
------------------------------------------
| Setup | # of alignment checks |
------------------------------------------
| unpatched, -O0 | 47195 |
| patched, -O0 | 30876 | (-34.6%)
------------------------------------------
llvm-svn: 301377
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 21 |
1 files changed, 9 insertions, 12 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 719147a58e0..d0aacf65428 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -533,15 +533,6 @@ bool CodeGenFunction::sanitizePerformTypeCheck() const { SanOpts.has(SanitizerKind::Vptr); } -/// Check if a runtime null check for \p Ptr can be omitted. -static bool canOmitPointerNullCheck(llvm::Value *Ptr) { - // Note: do not perform any constant-folding in this function. That is best - // left to the IR builder. - - // Pointers to alloca'd memory are non-null. - return isa<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases()); -} - void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, llvm::Value *Ptr, QualType Ty, CharUnits Alignment, @@ -560,11 +551,16 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, SmallVector<std::pair<llvm::Value *, SanitizerMask>, 3> Checks; llvm::BasicBlock *Done = nullptr; + // Quickly determine whether we have a pointer to an alloca. It's possible + // to skip null checks, and some alignment checks, for these pointers. This + // can reduce compile-time significantly. + auto PtrToAlloca = + dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases()); + bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast || TCK == TCK_UpcastToVirtualBase; if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) && - !SkippedChecks.has(SanitizerKind::Null) && - !canOmitPointerNullCheck(Ptr)) { + !SkippedChecks.has(SanitizerKind::Null) && !PtrToAlloca) { // The glvalue must not be an empty glvalue. llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr); @@ -617,7 +613,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); // The glvalue must be suitably aligned. - if (AlignVal > 1) { + if (AlignVal > 1 && + (!PtrToAlloca || PtrToAlloca->getAlignment() < AlignVal)) { llvm::Value *Align = Builder.CreateAnd(Builder.CreatePtrToInt(Ptr, IntPtrTy), llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); |