[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
This commit is contained in:
Vedant Kumar 2017-04-17 22:26:10 +00:00
parent 379d9c1dc6
commit dbbdda4d23
2 changed files with 19 additions and 9 deletions

View File

@ -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));
}
}
}

View File

@ -10,6 +10,8 @@ void load_non_null_pointers() {
int arr[1];
arr[0] = arr[0];
char c = "foo"[0];
// CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
// CHECK: ret void
}