https://github.com/serge-sans-paille updated 
https://github.com/llvm/llvm-project/pull/119704

>From 9d013f37df124fde0ed637d4b979de5ab01cbc22 Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguel...@mozilla.com>
Date: Thu, 12 Dec 2024 14:45:31 +0100
Subject: [PATCH 1/2] [clang] Generate appropriate assume in presence of libc's
 memcpy

It is an undefined behavior to pass null arguments as memcpy source or
destination parameter, so generate the appropriate llvm.assume call to
communicate this to the backend.

Don't do it for builtin memcpy as they don't suffer the same behavior in
case of null size.
---
 clang/lib/CodeGen/CGBuiltin.cpp           | 6 ++++++
 clang/test/CodeGen/catch-undef-behavior.c | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 497a0b3952af8c..50cd8529120d36 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4531,6 +4531,12 @@ 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) {
+      Builder.CreateAssumption(
+          Builder.CreateIsNotNull(Dest.emitRawPointer(*this)));
+      Builder.CreateAssumption(
+          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 7580290b0b0333..7ef7c78f1cebb7 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -371,6 +371,10 @@ void call_memcpy_nonnull(void *p, void *q, int sz) {
   // CHECK-TRAP: call void @llvm.ubsantrap(i8 16)
   // CHECK-COMMON-NOT: call
 
+  // CHECK-COMMON: %5 = icmp ne ptr %0, null
+  // CHECK-COMMON: call void @llvm.assume(i1 %5)
+  // CHECK-COMMON: %6 = icmp ne ptr %0, null
+  // CHECK-COMMON: call void @llvm.assume(i1 %6)
   // 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);
 }

>From 55f33c4edc2448b2573b89b6710959aae071f0ea Mon Sep 17 00:00:00 2001
From: serge-sans-paille <sguel...@mozilla.com>
Date: Fri, 13 Dec 2024 10:26:45 +0100
Subject: [PATCH 2/2] fixup! [clang] Generate appropriate assume in presence of
 libc's memcpy

---
 clang/lib/CodeGen/CGBuiltin.cpp           |  9 +++++----
 clang/test/CodeGen/catch-undef-behavior.c | 16 +++++++++-------
 2 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp
index 50cd8529120d36..20324515256678 100644
--- a/clang/lib/CodeGen/CGBuiltin.cpp
+++ b/clang/lib/CodeGen/CGBuiltin.cpp
@@ -4532,10 +4532,11 @@ RValue CodeGenFunction::EmitBuiltinExpr(const 
GlobalDecl GD, unsigned BuiltinID,
     EmitArgCheck(TCK_Store, Dest, E->getArg(0), 0);
     EmitArgCheck(TCK_Load, Src, E->getArg(1), 1);
     if (BuiltinID == Builtin::BImemcpy || BuiltinID == Builtin::BImempcpy) {
-      Builder.CreateAssumption(
-          Builder.CreateIsNotNull(Dest.emitRawPointer(*this)));
-      Builder.CreateAssumption(
-          Builder.CreateIsNotNull(Src.emitRawPointer(*this)));
+      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 ||
diff --git a/clang/test/CodeGen/catch-undef-behavior.c 
b/clang/test/CodeGen/catch-undef-behavior.c
index 7ef7c78f1cebb7..22161141acf4ad 100644
--- a/clang/test/CodeGen/catch-undef-behavior.c
+++ b/clang/test/CodeGen/catch-undef-behavior.c
@@ -366,15 +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: %5 = icmp ne ptr %0, null
-  // CHECK-COMMON: call void @llvm.assume(i1 %5)
-  // CHECK-COMMON: %6 = icmp ne ptr %0, null
-  // CHECK-COMMON: call void @llvm.assume(i1 %6)
+  //
+  // 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);
 }

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to