[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:
parent
379d9c1dc6
commit
dbbdda4d23
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue