diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 497a0b3952af8..2032451525667 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4531,6 +4531,13 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, Value *SizeVal = EmitScalarExpr(E->getArg(2)); EmitArgCheck(TCK_Store, Dest, E->getArg(0), 0); EmitArgCheck(TCK_Load, Src, E->getArg(1), 1); + if (BuiltinID == Builtin::BImemcpy || BuiltinID == Builtin::BImempcpy) { + Value *NullSize = Builder.CreateIsNull(SizeVal); + Builder.CreateAssumption(Builder.CreateOr( + NullSize, Builder.CreateIsNotNull(Dest.emitRawPointer(*this)))); + Builder.CreateAssumption(Builder.CreateOr( + NullSize, Builder.CreateIsNotNull(Src.emitRawPointer(*this)))); + } Builder.CreateMemCpy(Dest, Src, SizeVal, false); if (BuiltinID == Builtin::BImempcpy || BuiltinID == Builtin::BI__builtin_mempcpy) diff --git a/clang/test/CodeGen/catch-undef-behavior.c b/clang/test/CodeGen/catch-undef-behavior.c index 7580290b0b033..22161141acf4a 100644 --- a/clang/test/CodeGen/catch-undef-behavior.c +++ b/clang/test/CodeGen/catch-undef-behavior.c @@ -366,11 +366,17 @@ void call_memcpy_nonnull(void *p, void *q, int sz) { // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) // CHECK-COMMON-NOT: call - // CHECK-COMMON: icmp ne ptr {{.*}}, null + // CHECK-COMMON: icmp ne ptr %[[#]], null // CHECK-UBSAN: call void @__ubsan_handle_nonnull_arg // CHECK-TRAP: call void @llvm.ubsantrap(i8 16) - // CHECK-COMMON-NOT: call - + // + // CHECK-COMMON: icmp eq i64 %conv, 0 + // CHECK-COMMON: icmp ne ptr %0, null + // CHECK-COMMON: or i1 %[[#]], %[[#]] + // CHECK-COMMON: call void @llvm.assume(i1 %[[#]]) + // CHECK-COMMON: icmp ne ptr %1, null + // CHECK-COMMON: or i1 %[[#]], %[[#]] + // CHECK-COMMON: call void @llvm.assume(i1 %[[#]]) // CHECK-COMMON: call void @llvm.memcpy.p0.p0.i64(ptr align 1 %0, ptr align 1 %1, i64 %conv, i1 false) memcpy(p, q, sz); }