Author: vedantk Date: Tue Apr 25 21:17:21 2017 New Revision: 301377 URL: http://llvm.org/viewvc/llvm-project?rev=301377&view=rev Log: [ubsan] Skip alignment checks on allocas with known alignment
It's possible to determine the alignment of an alloca at compile-time. Use this information to skip emitting some runtime alignment checks. Testing: check-clang, check-ubsan. This significantly reduces the amount of alignment checks we emit when compiling X86ISelLowering.cpp. Here are the numbers from patched/unpatched clangs based on r301361. ------------------------------------------ | Setup | # of alignment checks | ------------------------------------------ | unpatched, -O0 | 47195 | | patched, -O0 | 30876 | (-34.6%) ------------------------------------------ Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp cfe/trunk/test/CodeGen/catch-undef-behavior.c cfe/trunk/test/CodeGen/sanitize-recover.c 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=301377&r1=301376&r2=301377&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Apr 25 21:17:21 2017 @@ -533,15 +533,6 @@ 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, @@ -560,11 +551,16 @@ void CodeGenFunction::EmitTypeCheck(Type SmallVector<std::pair<llvm::Value *, SanitizerMask>, 3> Checks; llvm::BasicBlock *Done = nullptr; + // Quickly determine whether we have a pointer to an alloca. It's possible + // to skip null checks, and some alignment checks, for these pointers. This + // can reduce compile-time significantly. + auto PtrToAlloca = + dyn_cast<llvm::AllocaInst>(Ptr->stripPointerCastsNoFollowAliases()); + bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast || TCK == TCK_UpcastToVirtualBase; if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) && - !SkippedChecks.has(SanitizerKind::Null) && - !canOmitPointerNullCheck(Ptr)) { + !SkippedChecks.has(SanitizerKind::Null) && !PtrToAlloca) { // The glvalue must not be an empty glvalue. llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr); @@ -617,7 +613,8 @@ void CodeGenFunction::EmitTypeCheck(Type AlignVal = getContext().getTypeAlignInChars(Ty).getQuantity(); // The glvalue must be suitably aligned. - if (AlignVal > 1) { + if (AlignVal > 1 && + (!PtrToAlloca || PtrToAlloca->getAlignment() < AlignVal)) { llvm::Value *Align = Builder.CreateAnd(Builder.CreatePtrToInt(Ptr, IntPtrTy), llvm::ConstantInt::get(IntPtrTy, AlignVal - 1)); Modified: cfe/trunk/test/CodeGen/catch-undef-behavior.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/catch-undef-behavior.c?rev=301377&r1=301376&r2=301377&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/catch-undef-behavior.c (original) +++ cfe/trunk/test/CodeGen/catch-undef-behavior.c Tue Apr 25 21:17:21 2017 @@ -36,13 +36,7 @@ void foo() { // CHECK-COMMON: %[[I8PTR:.*]] = bitcast i32* %[[PTR:.*]] to i8* // CHECK-COMMON-NEXT: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* %[[I8PTR]], i1 false, i1 false) - // CHECK-COMMON-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4 - - // CHECK-COMMON: %[[PTRTOINT:.*]] = ptrtoint {{.*}}* %[[PTR]] to i64 - // CHECK-COMMON-NEXT: %[[MISALIGN:.*]] = and i64 %[[PTRTOINT]], 3 - // CHECK-COMMON-NEXT: %[[CHECK1:.*]] = icmp eq i64 %[[MISALIGN]], 0 - - // CHECK-COMMON: %[[OK:.*]] = and i1 %[[CHECK0]], %[[CHECK1]] + // CHECK-COMMON-NEXT: %[[OK:.*]] = icmp uge i64 %[[SIZE]], 4 // CHECK-UBSAN: br i1 %[[OK]], {{.*}} !prof ![[WEIGHT_MD:.*]], !nosanitize // CHECK-TRAP: br i1 %[[OK]], {{.*}} Modified: cfe/trunk/test/CodeGen/sanitize-recover.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/sanitize-recover.c?rev=301377&r1=301376&r2=301377&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/sanitize-recover.c (original) +++ cfe/trunk/test/CodeGen/sanitize-recover.c Tue Apr 25 21:17:21 2017 @@ -22,15 +22,7 @@ void foo() { // PARTIAL: %[[SIZE:.*]] = call i64 @llvm.objectsize.i64.p0i8(i8* {{.*}}, i1 false, i1 false) // PARTIAL-NEXT: %[[CHECK0:.*]] = icmp uge i64 %[[SIZE]], 4 - // PARTIAL: %[[MISALIGN:.*]] = and i64 {{.*}}, 3 - // PARTIAL-NEXT: %[[CHECK1:.*]] = icmp eq i64 %[[MISALIGN]], 0 + // PARTIAL: br i1 %[[CHECK0]], {{.*}} !nosanitize - // PARTIAL: %[[CHECK01:.*]] = and i1 %[[CHECK1]], %[[CHECK0]] - - // PARTIAL: br i1 %[[CHECK01]], {{.*}} !nosanitize - // PARTIAL: br i1 %[[CHECK1]], {{.*}} !nosanitize - - // PARTIAL: call void @__ubsan_handle_type_mismatch_v1_abort( - // PARTIAL-NEXT: unreachable // PARTIAL: call void @__ubsan_handle_type_mismatch_v1( } 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=301377&r1=301376&r2=301377&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp (original) +++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Tue Apr 25 21:17:21 2017 @@ -12,6 +12,7 @@ void load_non_null_pointers() { char c = "foo"[0]; + // CHECK-NOT: and i64 {{.*}}, !nosanitize // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize // CHECK: ret void } @@ -43,10 +44,6 @@ struct A { }; f(); - // LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR:.*]] to i64, !nosanitize - // LAMBDA: and i64 %[[LAMBDAINT]], 7, !nosanitize - // LAMBDA: call void @__ubsan_handle_type_mismatch - // LAMBDA-NOT: call void @__ubsan_handle_type_mismatch // LAMBDA: ret void } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits