https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/234083
>From 41553adec6a7ad57ac9b6538938fb008d616b2e4 Mon Sep 17 00:00:00 2001 From: Vitaly Buka <[email protected]> Date: Tue, 20 Oct 2026 22:42:59 -0700 Subject: [PATCH 1/2] Rebase onto test regeneration Created using spr 2.0.0-beta.1 --- .../CodeGen/memcpy-inline-builtin-no-extern.c | 71 ++++++++++++++++++- 1 file changed, 68 insertions(+), 3 deletions(-) diff --git a/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c b/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c index f6edbbf6aeb44..7ce4e16d79345 100644 --- a/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c +++ b/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c @@ -1,5 +1,5 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-attributes --include-generated-funcs --version 6 // RUN: %clang_cc1 -triple x86_64 -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s -// // Verifies that clang-generated *.inline are flagged as internal. typedef unsigned long size_t; @@ -10,7 +10,6 @@ AVAILABLE_EXTERNALLY int memcmp(const void *a, const void *b, size_t c) { return __builtin_memcmp(a, b, c); } -// CHECK: internal{{.*}}memcmp.inline int bar(const void *a, const void *b, size_t c) { return memcmp(a, b, c); } @@ -23,7 +22,73 @@ TRIPLE_INLINE void *memcpy(void *a, const void *b, size_t c) { return __builtin_memcpy(a, b, c); } -// CHECK: internal{{.*}}memcpy.inline void *foo(void *a, const void *b, size_t c) { return memcpy(a, b, c); } +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define dso_local i32 @bar( +// CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]], i64 noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK-NEXT: store i64 [[C]], ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32 @memcmp.inline(ptr noundef [[TMP0]], ptr noundef [[TMP1]], i64 noundef [[TMP2]]) +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK: Function Attrs: alwaysinline nounwind +// CHECK-LABEL: define internal i32 @memcmp.inline( +// CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[C:%.*]]) #[[ATTR2:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK-NEXT: store i64 [[C]], ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call i32 @memcmp(ptr noundef [[TMP0]], ptr noundef [[TMP1]], i64 noundef [[TMP2]]) #[[ATTR4:[0-9]+]] +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK: Function Attrs: alwaysinline nounwind +// CHECK-LABEL: define internal ptr @memcpy.inline( +// CHECK-SAME: ptr [[A:%.*]], ptr [[B:%.*]], i64 [[C:%.*]]) #[[ATTR2]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK-NEXT: store i64 [[C]], ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[TMP0]], ptr align 1 [[TMP1]], i64 [[TMP2]], i1 false) +// CHECK-NEXT: ret ptr [[TMP0]] +// +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define dso_local ptr @foo( +// CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]], i64 noundef [[C:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[B_ADDR:%.*]] = alloca ptr, align 8 +// CHECK-NEXT: [[C_ADDR:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store ptr [[A]], ptr [[A_ADDR]], align 8 +// CHECK-NEXT: store ptr [[B]], ptr [[B_ADDR]], align 8 +// CHECK-NEXT: store i64 [[C]], ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[A_ADDR]], align 8 +// CHECK-NEXT: [[TMP1:%.*]] = load ptr, ptr [[B_ADDR]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[C_ADDR]], align 8 +// CHECK-NEXT: [[CALL:%.*]] = call ptr @memcpy.inline(ptr noundef [[TMP0]], ptr noundef [[TMP1]], i64 noundef [[TMP2]]) #[[ATTR4]] +// CHECK-NEXT: ret ptr [[CALL]] +// >From b94d59748f0f559f1c3567f25dacec6b6cc2cabd Mon Sep 17 00:00:00 2001 From: Vitaly Buka <[email protected]> Date: Tue, 20 Oct 2026 22:55:26 -0700 Subject: [PATCH 2/2] Split calling convention fix into separate PR Created using spr 2.0.0-beta.1 --- .../CodeGen/memcpy-inline-builtin-no-extern.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c b/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c index 7ce4e16d79345..a373346f5fcee 100644 --- a/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c +++ b/clang/test/CodeGen/memcpy-inline-builtin-no-extern.c @@ -25,6 +25,14 @@ TRIPLE_INLINE void *memcpy(void *a, const void *b, size_t c) { void *foo(void *a, const void *b, size_t c) { return memcpy(a, b, c); } + +AVAILABLE_EXTERNALLY __attribute__((preserve_most)) int umask(int m) { + return m; +} + +int call_umask(int m) { + return umask(m); +} // CHECK: Function Attrs: noinline nounwind optnone // CHECK-LABEL: define dso_local i32 @bar( // CHECK-SAME: ptr noundef [[A:%.*]], ptr noundef [[B:%.*]], i64 noundef [[C:%.*]]) #[[ATTR0:[0-9]+]] { @@ -92,3 +100,24 @@ void *foo(void *a, const void *b, size_t c) { // CHECK-NEXT: [[CALL:%.*]] = call ptr @memcpy.inline(ptr noundef [[TMP0]], ptr noundef [[TMP1]], i64 noundef [[TMP2]]) #[[ATTR4]] // CHECK-NEXT: ret ptr [[CALL]] // +// +// CHECK: Function Attrs: noinline nounwind optnone +// CHECK-LABEL: define dso_local i32 @call_umask( +// CHECK-SAME: i32 noundef [[M:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[M_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[M]], ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[CALL:%.*]] = call preserve_mostcc i32 @umask.inline(i32 noundef [[TMP0]]) #[[ATTR4]] +// CHECK-NEXT: ret i32 [[CALL]] +// +// +// CHECK: Function Attrs: alwaysinline nounwind +// CHECK-LABEL: define internal i32 @umask.inline( +// CHECK-SAME: i32 [[M:%.*]]) #[[ATTR2]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[M_ADDR:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store i32 [[M]], ptr [[M_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[M_ADDR]], align 4 +// CHECK-NEXT: ret i32 [[TMP0]] +// _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
