]> granicus.if.org Git - clang/commitdiff
[ubsan] Skip alignment checks which are folded away
authorVedant Kumar <vsk@apple.com>
Tue, 3 Oct 2017 01:27:26 +0000 (01:27 +0000)
committerVedant Kumar <vsk@apple.com>
Tue, 3 Oct 2017 01:27:26 +0000 (01:27 +0000)
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

lib/CodeGen/CGExpr.cpp
test/CodeGenCXX/ubsan-suppress-checks.cpp

index e87c4a9e2ed38fd75e9b355abfe2179b706d5eb0..cd2e8e14bc697861ecb66b4ba6c5052a26b5db27 100644 (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));
     }
   }
 
index ae7c94b34f2903db3eb9facb70039fae15c576f1..fa7ea29d94f2047987c235d8cb06b909aa7fa50f 100644 (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();
 }