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/4] [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/4] [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 f8724ed1054aa654974de8c9f443ba14a327405f Mon Sep 17 00:00:00 2001 From: AkshayK <[email protected]> Date: Wed, 15 Jul 2026 20:00:29 -0400 Subject: [PATCH 3/4] [CIR] Run var_arg.c under -std=c23 with a single RUN set --- clang/test/CIR/CodeGen/var_arg.c | 71 +++++++++++++++----------------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/clang/test/CIR/CodeGen/var_arg.c b/clang/test/CIR/CodeGen/var_arg.c index 40861667e5ba7..f95bb9ef6a217 100644 --- a/clang/test/CIR/CodeGen/var_arg.c +++ b/clang/test/CIR/CodeGen/var_arg.c @@ -1,20 +1,12 @@ -// 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: %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 -triple x86_64-unknown-linux-gnu -Wno-unused-value -emit-llvm %s -o %t.ll +// 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=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 +// no named parameters. // 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 } @@ -264,11 +256,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 +265,26 @@ 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-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 %{{.+}}) -// 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 %{{.+}}) +// OGCG-LABEL: define {{.*}}void @noargs(...) +// OGCG: %[[VAAREA:.+]] = alloca [1 x %struct.__va_list_tag] +// OGCG: call void @llvm.va_start.p0(ptr %{{.+}}) +// OGCG: call void @llvm.va_start.p0(ptr %{{.+}}) +// OGCG: call void @llvm.va_end.p0(ptr %{{.+}}) void with_param(int count, ...) { __builtin_va_list list; @@ -297,12 +292,14 @@ 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> +// 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-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 %{{.+}}) +// LLVM-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) +// LLVM: call void @llvm.va_start.p0(ptr %{{.+}}) +// LLVM: call void @llvm.va_end.p0(ptr %{{.+}}) -#endif // __STDC_VERSION__ >= 202311L +// OGCG-LABEL: define {{.*}}void @with_param(i32 noundef %{{.+}}, ...) +// OGCG: call void @llvm.va_start.p0(ptr %{{.+}}) +// OGCG: call void @llvm.va_end.p0(ptr %{{.+}}) >From f5e18ca5060ab0d6d20af4edf0b8006fd0537ece Mon Sep 17 00:00:00 2001 From: AkshayK <[email protected]> Date: Thu, 16 Jul 2026 11:19:41 -0400 Subject: [PATCH 4/4] Retrigger premerge CI (AArch64 LLDB flake, llvm/llvm-project#209874) _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
