mirror of https://github.com/microsoft/clang.git
[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:
parent
9ce2dd4d7e
commit
3f7b4f37be
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue