diff options
author | Vedant Kumar <vsk@apple.com> | 2017-04-17 22:26:10 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-04-17 22:26:10 +0000 |
commit | dbbdda4d23c514b7a1f1817d246d58fba0cad783 (patch) | |
tree | 302f28e2afe1a484dc6626fd28b348aef717a92f /clang/lib/CodeGen/CGExpr.cpp | |
parent | 379d9c1dc6c019eacf851ba1acfaefe8e5f2a587 (diff) | |
download | bcm5719-llvm-dbbdda4d23c514b7a1f1817d246d58fba0cad783.tar.gz bcm5719-llvm-dbbdda4d23c514b7a1f1817d246d58fba0cad783.zip |
[ubsan] Skip null checks if they are constant-folded away
The IR builder can constant-fold null checks if the pointer operand
points to a constant. If the "is-non-null" check is folded away to
"true", don't emit the null check + branch.
Testing: check-clang, check-ubsan.
This slightly reduces the amount of null checks we emit when compiling
X86ISelLowering.cpp. Here are the numbers from patched/unpatched clangs
based on r300371.
-------------------------------------
| Setup | # of null checks |
-------------------------------------
| unpatched, -O0 | 25251 |
| patched, -O0 | 23925 | (-5.3%)
-------------------------------------
llvm-svn: 300509
Diffstat (limited to 'clang/lib/CodeGen/CGExpr.cpp')
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index b5d6c659e9e..719147a58e0 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -568,15 +568,23 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, // The glvalue must not be an empty glvalue. llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr); - if (AllowNullPointers) { - // When performing pointer casts, it's OK if the value is null. - // Skip the remaining checks in that case. - Done = createBasicBlock("null"); - llvm::BasicBlock *Rest = createBasicBlock("not.null"); - Builder.CreateCondBr(IsNonNull, Rest, Done); - EmitBlock(Rest); - } else { - Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + // The IR builder can constant-fold the null check if the pointer points to + // a constant. + bool PtrIsNonNull = + IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext()); + + // Skip the null check if the pointer is known to be non-null. + if (!PtrIsNonNull) { + if (AllowNullPointers) { + // When performing pointer casts, it's OK if the value is null. + // Skip the remaining checks in that case. + Done = createBasicBlock("null"); + llvm::BasicBlock *Rest = createBasicBlock("not.null"); + Builder.CreateCondBr(IsNonNull, Rest, Done); + EmitBlock(Rest); + } else { + Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + } } } |