https://github.com/kumarak updated https://github.com/llvm/llvm-project/pull/208741
>From b97f5642ec7c8f970b04209022496390dc5af0d4 Mon Sep 17 00:00:00 2001 From: AkshayK <[email protected]> Date: Fri, 10 Jul 2026 10:30:16 -0400 Subject: [PATCH 1/3] [CIR] Handle __builtin_c23_va_start C23 va_start expands to __builtin_c23_va_start, which was hitting the unimplemented-builtin NYI path, so all variadic code failed to compile with -fclangir in -std=c23 mode. Lower it exactly like __builtin_va_start: the va_list is always arg 0. --- clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp | 1 + clang/test/CIR/CodeGen/var_arg-c23.c | 41 +++++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 clang/test/CIR/CodeGen/var_arg-c23.c diff --git a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp index 3c48b8b67d9ee..84bb33663de05 100644 --- a/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenBuiltin.cpp @@ -1059,6 +1059,7 @@ RValue CIRGenFunction::emitBuiltinExpr(const GlobalDecl &gd, unsigned builtinID, // C stdarg builtins. case Builtin::BI__builtin_stdarg_start: case Builtin::BI__builtin_va_start: + case Builtin::BI__builtin_c23_va_start: case Builtin::BI__va_start: { mlir::Value vaList = builtinID == Builtin::BI__va_start ? emitScalarExpr(e->getArg(0)) diff --git a/clang/test/CIR/CodeGen/var_arg-c23.c b/clang/test/CIR/CodeGen/var_arg-c23.c new file mode 100644 index 0000000000000..1bb0b7099b5fe --- /dev/null +++ b/clang/test/CIR/CodeGen/var_arg-c23.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM + +void noargs(...) { + __builtin_va_list list; + __builtin_va_start(list, 0); + __builtin_c23_va_start(list); + __builtin_va_end(list); +} + +// CIR-LABEL: cir.func {{.*}} @noargs( +// CIR: %[[VAAREA:.+]] = cir.alloca "list" {{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> +// CIR: %[[VA_PTR0:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] +// CIR-NEXT: cir.va_start %[[VA_PTR0]] : !cir.ptr<!rec___va_list_tag> +// CIR: %[[VA_PTR1:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] +// CIR-NEXT: cir.va_start %[[VA_PTR1]] : !cir.ptr<!rec___va_list_tag> +// CIR: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> + +// LLVM-LABEL: define {{.*}}void @noargs(...) +// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) + +void with_param(int count, ...) { + __builtin_va_list list; + __builtin_c23_va_start(list, count); + __builtin_va_end(list); +} + +// CIR-LABEL: cir.func {{.*}} @with_param( +// CIR: cir.va_start %{{.+}} : !cir.ptr<!rec___va_list_tag> +// CIR: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> + +// LLVM-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) >From 14d47b5bf40354f2bd61e63abb164349a2ef8205 Mon Sep 17 00:00:00 2001 From: AkshayK <[email protected]> Date: Wed, 15 Jul 2026 13:29:29 -0400 Subject: [PATCH 2/3] [CIR] Merge C23 va_start test into var_arg.c --- clang/test/CIR/CodeGen/var_arg-c23.c | 41 --------------------- clang/test/CIR/CodeGen/var_arg.c | 54 ++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 41 deletions(-) delete mode 100644 clang/test/CIR/CodeGen/var_arg-c23.c diff --git a/clang/test/CIR/CodeGen/var_arg-c23.c b/clang/test/CIR/CodeGen/var_arg-c23.c deleted file mode 100644 index 1bb0b7099b5fe..0000000000000 --- a/clang/test/CIR/CodeGen/var_arg-c23.c +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir -// RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll -// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll -// RUN: FileCheck --input-file=%t.ll %s -check-prefix=LLVM - -void noargs(...) { - __builtin_va_list list; - __builtin_va_start(list, 0); - __builtin_c23_va_start(list); - __builtin_va_end(list); -} - -// CIR-LABEL: cir.func {{.*}} @noargs( -// CIR: %[[VAAREA:.+]] = cir.alloca "list" {{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -// CIR: %[[VA_PTR0:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] -// CIR-NEXT: cir.va_start %[[VA_PTR0]] : !cir.ptr<!rec___va_list_tag> -// CIR: %[[VA_PTR1:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] -// CIR-NEXT: cir.va_start %[[VA_PTR1]] : !cir.ptr<!rec___va_list_tag> -// CIR: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> - -// LLVM-LABEL: define {{.*}}void @noargs(...) -// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] -// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) - -void with_param(int count, ...) { - __builtin_va_list list; - __builtin_c23_va_start(list, count); - __builtin_va_end(list); -} - -// CIR-LABEL: cir.func {{.*}} @with_param( -// CIR: cir.va_start %{{.+}} : !cir.ptr<!rec___va_list_tag> -// CIR: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> - -// LLVM-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) -// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) diff --git a/clang/test/CIR/CodeGen/var_arg.c b/clang/test/CIR/CodeGen/var_arg.c index 7204cef68578b..40861667e5ba7 100644 --- a/clang/test/CIR/CodeGen/var_arg.c +++ b/clang/test/CIR/CodeGen/var_arg.c @@ -4,6 +4,17 @@ // RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll // RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG +// +// C23 is required for __builtin_c23_va_start and for variadic functions with +// no named parameters; the *-C23 prefixes check the guarded functions at the +// end of this file. The LLVM-C23 checks are shared between the ClangIR +// pipeline and OG CodeGen. +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.c23.cir +// RUN: FileCheck --input-file=%t.c23.cir %s -check-prefix=CIR-C23 +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.c23.ll +// RUN: FileCheck --input-file=%t-cir.c23.ll %s -check-prefix=LLVM-C23 +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.c23.ll +// RUN: FileCheck --input-file=%t.c23.ll %s -check-prefix=LLVM-C23 // CIR: !rec___va_list_tag = !cir.struct<"__va_list_tag" {!u32i, !u32i, !cir.ptr<!void>, !cir.ptr<!void>} // LLVM: %struct.__va_list_tag = type { i32, i32, ptr, ptr } @@ -252,3 +263,46 @@ int varargs_new(char *fmt, ...) { // OGCG: call void @llvm.va_end.p0(ptr %[[DECAY2]]) // OGCG: %[[VAL:.+]] = load i32, ptr %[[RES_ADDR]] // OGCG: ret i32 %[[VAL]] + +// C23 only: __builtin_c23_va_start and variadic functions with no named +// parameters. Ensure that __builtin_va_start(list, 0) and +// __builtin_c23_va_start(list) have the same codegen. +#if __STDC_VERSION__ >= 202311L + +void noargs(...) { + __builtin_va_list list; + __builtin_va_start(list, 0); + __builtin_c23_va_start(list); + __builtin_va_end(list); +} + +// CIR-C23-LABEL: cir.func {{.*}} @noargs( +// CIR-C23: %[[VAAREA:.+]] = cir.alloca "list" {{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> +// CIR-C23: %[[VA_PTR0:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-C23-NEXT: cir.va_start %[[VA_PTR0]] : !cir.ptr<!rec___va_list_tag> +// CIR-C23: %[[VA_PTR1:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-C23-NEXT: cir.va_start %[[VA_PTR1]] : !cir.ptr<!rec___va_list_tag> +// CIR-C23: %[[VA_PTR2:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-C23-NEXT: cir.va_end %[[VA_PTR2]] : !cir.ptr<!rec___va_list_tag> + +// LLVM-C23-LABEL: define {{.*}}void @noargs(...) +// LLVM-C23: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] +// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM-C23: call void @llvm.va_end.p0(ptr %{{.+}}) + +void with_param(int count, ...) { + __builtin_va_list list; + __builtin_c23_va_start(list, count); + __builtin_va_end(list); +} + +// CIR-C23-LABEL: cir.func {{.*}} @with_param( +// CIR-C23: cir.va_start %{{.+}} : !cir.ptr<!rec___va_list_tag> +// CIR-C23: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> + +// LLVM-C23-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) +// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM-C23: call void @llvm.va_end.p0(ptr %{{.+}}) + +#endif // __STDC_VERSION__ >= 202311L >From 32829b13223a871ffd292b7c50dc951c96cc0720 Mon Sep 17 00:00:00 2001 From: AkshayK <[email protected]> Date: Wed, 15 Jul 2026 20:00:29 -0400 Subject: [PATCH 3/3] [CIR] Run var_arg.c under -std=c23 with a single RUN set --- clang/test/CIR/CodeGen/var_arg.c | 174 ++++++++++++++----------------- 1 file changed, 81 insertions(+), 93 deletions(-) diff --git a/clang/test/CIR/CodeGen/var_arg.c b/clang/test/CIR/CodeGen/var_arg.c index 40861667e5ba7..6a711ae4afa69 100644 --- a/clang/test/CIR/CodeGen/var_arg.c +++ b/clang/test/CIR/CodeGen/var_arg.c @@ -1,24 +1,17 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.cir // RUN: FileCheck --input-file=%t.cir %s -check-prefix=CIR -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll -// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefix=LLVM -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll -// RUN: FileCheck --input-file=%t.ll %s -check-prefix=OGCG +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.ll +// RUN: FileCheck --input-file=%t-cir.ll %s -check-prefixes=LLVM,LLVM-CIR +// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// RUN: FileCheck --input-file=%t.ll %s -check-prefixes=OGCG,LLVM // // C23 is required for __builtin_c23_va_start and for variadic functions with -// no named parameters; the *-C23 prefixes check the guarded functions at the -// end of this file. The LLVM-C23 checks are shared between the ClangIR -// pipeline and OG CodeGen. -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-cir %s -o %t.c23.cir -// RUN: FileCheck --input-file=%t.c23.cir %s -check-prefix=CIR-C23 -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -fclangir -emit-llvm %s -o %t-cir.c23.ll -// RUN: FileCheck --input-file=%t-cir.c23.ll %s -check-prefix=LLVM-C23 -// RUN: %clang_cc1 -std=c23 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.c23.ll -// RUN: FileCheck --input-file=%t.c23.ll %s -check-prefix=LLVM-C23 +// no named parameters. LLVM checks lines where the ClangIR pipeline and OG +// CodeGen emit identical LLVM IR; LLVM-CIR and OGCG check the lines where +// the two pipelines differ. // CIR: !rec___va_list_tag = !cir.struct<"__va_list_tag" {!u32i, !u32i, !cir.ptr<!void>, !cir.ptr<!void>} // LLVM: %struct.__va_list_tag = type { i32, i32, ptr, ptr } -// OGCG: %struct.__va_list_tag = type { i32, i32, ptr, ptr } int varargs(int count, ...) { __builtin_va_list args; @@ -44,22 +37,22 @@ int varargs(int count, ...) { // CIR: %[[RETVAL:.+]] = cir.load{{.*}} %[[RET_ADDR]] : !cir.ptr<!s32i>, !s32i // CIR: cir.return %[[RETVAL]] : !s32i -// LLVM-LABEL: define dso_local i32 @varargs( -// LLVM: %[[COUNT_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[RET_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} -// LLVM: %[[RES_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) -// LLVM: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 -// LLVM: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} -// LLVM: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) -// LLVM: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} -// LLVM: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} -// LLVM: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} -// LLVM: ret i32 %[[RETVAL]] +// LLVM-CIR-LABEL: define dso_local i32 @varargs( +// LLVM-CIR: %[[COUNT_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[RET_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} +// LLVM-CIR: %[[RES_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) +// LLVM-CIR: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 +// LLVM-CIR: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) +// LLVM-CIR: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: ret i32 %[[RETVAL]] // OGCG-LABEL: define dso_local i32 @varargs // OGCG: %[[COUNT_ADDR:.+]] = alloca i32 @@ -117,22 +110,22 @@ int stdarg_start(int count, ...) { // CIR: %[[RETVAL:.+]] = cir.load{{.*}} %[[RET_ADDR]] : !cir.ptr<!s32i>, !s32i // CIR: cir.return %[[RETVAL]] : !s32i -// LLVM-LABEL: define dso_local i32 @stdarg_start( -// LLVM: %[[COUNT_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[RET_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} -// LLVM: %[[RES_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) -// LLVM: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 -// LLVM: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} -// LLVM: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) -// LLVM: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} -// LLVM: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} -// LLVM: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} -// LLVM: ret i32 %[[RETVAL]] +// LLVM-CIR-LABEL: define dso_local i32 @stdarg_start( +// LLVM-CIR: %[[COUNT_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[RET_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} +// LLVM-CIR: %[[RES_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) +// LLVM-CIR: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 +// LLVM-CIR: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) +// LLVM-CIR: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: ret i32 %[[RETVAL]] // OGCG-LABEL: define dso_local i32 @stdarg_start // OGCG: %[[COUNT_ADDR:.+]] = alloca i32 @@ -180,10 +173,10 @@ void stdarg_copy() { // CIR: %{{.*}} = cir.cast array_to_ptrdecay %{{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> // CIR: cir.va_copy %{{.*}} to %{{.*}} : !cir.ptr<!rec___va_list_tag>, !cir.ptr<!rec___va_list_tag> -// LLVM-LABEL: @stdarg_copy -// LLVM: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}} -// LLVM: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}} -// LLVM: call void @llvm.va_copy.p0(ptr %{{.*}}, ptr %{{.*}} +// LLVM-CIR-LABEL: @stdarg_copy +// LLVM-CIR: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}} +// LLVM-CIR: %{{.*}} = getelementptr %struct.__va_list_tag, ptr %{{.*}} +// LLVM-CIR: call void @llvm.va_copy.p0(ptr %{{.*}}, ptr %{{.*}} // OGCG-LABEL: @stdarg_copy // OGCG: %{{.*}} = getelementptr inbounds [1 x %struct.__va_list_tag], ptr %{{.*}} @@ -215,22 +208,22 @@ int varargs_new(char *fmt, ...) { // CIR: %[[RETVAL:.+]] = cir.load{{.*}} %[[RET_ADDR]] : !cir.ptr<!s32i>, !s32i // CIR: cir.return %[[RETVAL]] : !s32i -// LLVM-LABEL: define dso_local i32 @varargs_new( -// LLVM: %[[FMT_ADDR:.+]] = alloca ptr -// LLVM: %[[RET_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} -// LLVM: %[[RES_ADDR:.+]] = alloca i32{{.*}} -// LLVM: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) -// LLVM: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 -// LLVM: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} -// LLVM: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 -// LLVM: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) -// LLVM: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} -// LLVM: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} -// LLVM: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} -// LLVM: ret i32 %[[RETVAL]] +// LLVM-CIR-LABEL: define dso_local i32 @varargs_new( +// LLVM-CIR: %[[FMT_ADDR:.+]] = alloca ptr +// LLVM-CIR: %[[RET_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag]{{.*}} +// LLVM-CIR: %[[RES_ADDR:.+]] = alloca i32{{.*}} +// LLVM-CIR: %[[VA_PTR0:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_start.p0(ptr %[[VA_PTR0]]) +// LLVM-CIR: %[[VA_PTR1:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: %[[VA_ARG:.+]] = va_arg ptr %[[VA_PTR1]], i32 +// LLVM-CIR: store i32 %[[VA_ARG]], ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: %[[VA_PTR2:.+]] = getelementptr %struct.__va_list_tag, ptr %[[VAAREA]], i32 0 +// LLVM-CIR: call void @llvm.va_end.p0(ptr %[[VA_PTR2]]) +// LLVM-CIR: %[[TMP_LOAD:.+]] = load i32, ptr %[[RES_ADDR]], {{.*}} +// LLVM-CIR: store i32 %[[TMP_LOAD]], ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: %[[RETVAL:.+]] = load i32, ptr %[[RET_ADDR]], {{.*}} +// LLVM-CIR: ret i32 %[[RETVAL]] // OGCG-LABEL: define dso_local i32 @varargs_new // OGCG: %[[FMT_ADDR:.+]] = alloca ptr @@ -264,11 +257,8 @@ int varargs_new(char *fmt, ...) { // OGCG: %[[VAL:.+]] = load i32, ptr %[[RES_ADDR]] // OGCG: ret i32 %[[VAL]] -// C23 only: __builtin_c23_va_start and variadic functions with no named -// parameters. Ensure that __builtin_va_start(list, 0) and -// __builtin_c23_va_start(list) have the same codegen. -#if __STDC_VERSION__ >= 202311L - +// Ensure that __builtin_va_start(list, 0) and __builtin_c23_va_start(list) +// have the same codegen. void noargs(...) { __builtin_va_list list; __builtin_va_start(list, 0); @@ -276,20 +266,20 @@ void noargs(...) { __builtin_va_end(list); } -// CIR-C23-LABEL: cir.func {{.*}} @noargs( -// CIR-C23: %[[VAAREA:.+]] = cir.alloca "list" {{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -// CIR-C23: %[[VA_PTR0:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> -// CIR-C23-NEXT: cir.va_start %[[VA_PTR0]] : !cir.ptr<!rec___va_list_tag> -// CIR-C23: %[[VA_PTR1:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> -// CIR-C23-NEXT: cir.va_start %[[VA_PTR1]] : !cir.ptr<!rec___va_list_tag> -// CIR-C23: %[[VA_PTR2:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> -// CIR-C23-NEXT: cir.va_end %[[VA_PTR2]] : !cir.ptr<!rec___va_list_tag> +// CIR-LABEL: cir.func {{.*}} @noargs( +// CIR: %[[VAAREA:.+]] = cir.alloca "list" {{.*}} : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> +// CIR: %[[VA_PTR0:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-NEXT: cir.va_start %[[VA_PTR0]] : !cir.ptr<!rec___va_list_tag> +// CIR: %[[VA_PTR1:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-NEXT: cir.va_start %[[VA_PTR1]] : !cir.ptr<!rec___va_list_tag> +// CIR: %[[VA_PTR2:.+]] = cir.cast array_to_ptrdecay %[[VAAREA]] : !cir.ptr<!cir.array<!rec___va_list_tag x 1>> -> !cir.ptr<!rec___va_list_tag> +// CIR-NEXT: cir.va_end %[[VA_PTR2]] : !cir.ptr<!rec___va_list_tag> -// LLVM-C23-LABEL: define {{.*}}void @noargs(...) -// LLVM-C23: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] -// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM-C23: call void @llvm.va_end.p0(ptr %{{.+}}) +// LLVM-LABEL: define {{.*}}void @noargs(...) +// LLVM: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) void with_param(int count, ...) { __builtin_va_list list; @@ -297,12 +287,10 @@ void with_param(int count, ...) { __builtin_va_end(list); } -// CIR-C23-LABEL: cir.func {{.*}} @with_param( -// CIR-C23: cir.va_start %{{.+}} : !cir.ptr<!rec___va_list_tag> -// CIR-C23: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> - -// LLVM-C23-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) -// LLVM-C23: call void @llvm.va_start.p0(ptr %{{.+}}) -// LLVM-C23: call void @llvm.va_end.p0(ptr %{{.+}}) +// CIR-LABEL: cir.func {{.*}} @with_param( +// CIR: cir.va_start %{{.+}} : !cir.ptr<!rec___va_list_tag> +// CIR: cir.va_end %{{.+}} : !cir.ptr<!rec___va_list_tag> -#endif // __STDC_VERSION__ >= 202311L +// LLVM-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
