Author: vedantk Date: Mon Apr 17 17:26:10 2017 New Revision: 300509 URL: http://llvm.org/viewvc/llvm-project?rev=300509&view=rev Log: [ubsan] Skip null checks if they are constant-folded away
The IR builder can constant-fold null checks if the pointer operand points to a constant. If the "is-non-null" check is folded away to "true", don't emit the null check + branch. Testing: check-clang, check-ubsan. This slightly 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 | 25251 | | patched, -O0 | 23925 | (-5.3%) ------------------------------------- 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=300509&r1=300508&r2=300509&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CGExpr.cpp (original) +++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Apr 17 17:26:10 2017 @@ -568,15 +568,23 @@ void CodeGenFunction::EmitTypeCheck(Type // The glvalue must not be an empty glvalue. llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr); - if (AllowNullPointers) { - // When performing pointer casts, it's OK if the value is null. - // Skip the remaining checks in that case. - Done = createBasicBlock("null"); - llvm::BasicBlock *Rest = createBasicBlock("not.null"); - Builder.CreateCondBr(IsNonNull, Rest, Done); - EmitBlock(Rest); - } else { - Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + // The IR builder can constant-fold the null check if the pointer points to + // a constant. + bool PtrIsNonNull = + IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext()); + + // Skip the null check if the pointer is known to be non-null. + if (!PtrIsNonNull) { + if (AllowNullPointers) { + // When performing pointer casts, it's OK if the value is null. + // Skip the remaining checks in that case. + Done = createBasicBlock("null"); + llvm::BasicBlock *Rest = createBasicBlock("not.null"); + Builder.CreateCondBr(IsNonNull, Rest, Done); + EmitBlock(Rest); + } else { + Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null)); + } } } 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=300509&r1=300508&r2=300509&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp (original) +++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Mon Apr 17 17:26:10 2017 @@ -10,6 +10,8 @@ void load_non_null_pointers() { int arr[1]; arr[0] = arr[0]; + char c = "foo"[0]; + // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize // CHECK: ret void } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits