[ubsan] Skip alignment checks which are folded away

Don't emit alignment checks which the IR constant folder throws away.

I've tested this out on X86FastISel.cpp. While this doesn't decrease
end-to-end compile-time significantly, it results in 122 fewer type
checks (1% reduction) overall, without adding any real complexity.

Differential Revision: https://reviews.llvm.org/D37544

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@314752 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vedant Kumar 2017-10-03 01:27:26 +00:00
parent 9ce2dd4d7e
commit 3f7b4f37be
2 changed files with 16 additions and 3 deletions

View File

@ -618,6 +618,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
auto PtrToAlloca =
dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
llvm::Value *True = llvm::ConstantInt::getTrue(getLLVMContext());
llvm::Value *IsNonNull = nullptr;
bool IsGuaranteedNonNull =
SkippedChecks.has(SanitizerKind::Null) || PtrToAlloca;
@ -629,8 +630,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
// The IR builder can constant-fold the null check if the pointer points to
// a constant.
IsGuaranteedNonNull =
IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
IsGuaranteedNonNull = IsNonNull == True;
// Skip the null check if the pointer is known to be non-null.
if (!IsGuaranteedNonNull) {
@ -684,7 +684,8 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
PtrAsInt, llvm::ConstantInt::get(IntPtrTy, AlignVal - 1));
llvm::Value *Aligned =
Builder.CreateICmpEQ(Align, llvm::ConstantInt::get(IntPtrTy, 0));
Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
if (Aligned != True)
Checks.push_back(std::make_pair(Aligned, SanitizerKind::Alignment));
}
}

View File

@ -17,6 +17,17 @@ void load_non_null_pointers() {
// CHECK: ret void
}
// CHECK-LABEL: define void @_Z31use_us16_aligned_array_elementsv
void use_us16_aligned_array_elements() {
static const unsigned short Arr[] = {0, 1, 2};
auto use_array = [](const unsigned short(&X)[3]) -> void {};
use_array(Arr);
// CHECK-NOT: br i1 true
// ALIGN-NOT: call void @__ubsan_handle_type_mismatch
// CHECK: ret void
}
struct A {
int foo;
@ -229,4 +240,5 @@ void force_irgen() {
d->load_member_3();
load_non_null_pointers();
use_us16_aligned_array_elements();
}