r300508 - [ubsan] Skip null checks on pointers to the start of an alloca
Vedant Kumar via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 17 15:26:07 PDT 2017
Author: vedantk
Date: Mon Apr 17 17:26:07 2017
New Revision: 300508
URL: http://llvm.org/viewvc/llvm-project?rev=300508&view=rev
Log:
[ubsan] Skip null checks on pointers to the start of an alloca
Pointers to the start of an alloca are non-null, so we don't need to
emit runtime null checks for them.
Testing: check-clang, check-ubsan.
This significantly 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 | 45439 |
| patched, -O0 | 25251 | (-44.4%)
-------------------------------------
Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=300508&r1=300507&r2=300508&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Apr 17 17:26:07 2017
@@ -533,6 +533,15 @@ bool CodeGenFunction::sanitizePerformTyp
SanOpts.has(SanitizerKind::Vptr);
}
+/// Check if a runtime null check for \p Ptr can be omitted.
+static bool canOmitPointerNullCheck(llvm::Value *Ptr) {
+ // Note: do not perform any constant-folding in this function. That is best
+ // left to the IR builder.
+
+ // Pointers to alloca'd memory are non-null.
+ return isa<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases());
+}
+
void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
llvm::Value *Ptr, QualType Ty,
CharUnits Alignment,
@@ -554,7 +563,8 @@ void CodeGenFunction::EmitTypeCheck(Type
bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
TCK == TCK_UpcastToVirtualBase;
if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
- !SkippedChecks.has(SanitizerKind::Null)) {
+ !SkippedChecks.has(SanitizerKind::Null) &&
+ !canOmitPointerNullCheck(Ptr)) {
// The glvalue must not be an empty glvalue.
llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
Modified: cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp?rev=300508&r1=300507&r2=300508&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Mon Apr 17 17:26:07 2017
@@ -2,6 +2,18 @@
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL
// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s -fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA
+// CHECK-LABEL: define void @_Z22load_non_null_pointersv
+void load_non_null_pointers() {
+ int var;
+ var = *&var;
+
+ int arr[1];
+ arr[0] = arr[0];
+
+ // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
+ // CHECK: ret void
+}
+
struct A {
int foo;
@@ -29,8 +41,7 @@ struct A {
};
f();
- // LAMBDA: icmp ne %class.anon* %[[FUNCVAR:.*]], null, !nosanitize
- // LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR]] to i64, !nosanitize
+ // LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR:.*]] to i64, !nosanitize
// LAMBDA: and i64 %[[LAMBDAINT]], 7, !nosanitize
// LAMBDA: call void @__ubsan_handle_type_mismatch
@@ -127,8 +138,8 @@ struct A {
struct B {
operator A*() const { return nullptr; }
- // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEv
- static int load_member() {
+ // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_
+ static int load_member(B *bp) {
// Check &b before converting it to an A*.
// CHECK: call void @__ubsan_handle_type_mismatch
//
@@ -136,8 +147,7 @@ struct B {
// NULL: call void @__ubsan_handle_type_mismatch
//
// CHECK-NOT: call void @__ubsan_handle_type_mismatch
- B b;
- return static_cast<A *>(b)->load_member();
+ return static_cast<A *>(*bp)->load_member();
// CHECK: ret i32
}
};
@@ -210,7 +220,7 @@ void force_irgen() {
A::call_through_reference(*a);
A::call_through_pointer(a);
- B::load_member();
+ B::load_member(nullptr);
Base *b = new Derived;
b->load_member_1();
@@ -218,4 +228,6 @@ void force_irgen() {
Derived *d;
d->load_member_2();
d->load_member_3();
+
+ load_non_null_pointers();
}
More information about the cfe-commits
mailing list