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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits