Author: Folkert de Vries Date: 2026-08-26T10:59:12+02:00 New Revision: d68717a4621010f9c2cc953113c08884b5906eec
URL: https://github.com/llvm/llvm-project/commit/d68717a4621010f9c2cc953113c08884b5906eec DIFF: https://github.com/llvm/llvm-project/commit/d68717a4621010f9c2cc953113c08884b5906eec.diff LOG: [NFC][Sparc] add more V8 `va_arg` tests (#218720) pre-commit for https://github.com/llvm/llvm-project/pull/214981 Added: Modified: clang/test/CodeGen/Sparc/sparc-vaarg.c Removed: ################################################################################ diff --git a/clang/test/CodeGen/Sparc/sparc-vaarg.c b/clang/test/CodeGen/Sparc/sparc-vaarg.c index b78949e09350c..53d215f479fae 100644 --- a/clang/test/CodeGen/Sparc/sparc-vaarg.c +++ b/clang/test/CodeGen/Sparc/sparc-vaarg.c @@ -1,34 +1,176 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 6 // RUN: %clang_cc1 -triple sparc -emit-llvm -o - %s | FileCheck %s #include <stdarg.h> -// CHECK-LABEL: define{{.*}} i32 @get_int -// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, i32{{$}} -// CHECK: store i32 [[RESULT]], ptr [[LOC:%[a-z_0-9]+]] -// CHECK: [[RESULT2:%[a-z_0-9]+]] = load i32, ptr [[LOC]] -// CHECK: ret i32 [[RESULT2]] +// CHECK-LABEL: define dso_local i32 @get_int( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[VARET:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], i32 +// CHECK-NEXT: store i32 [[TMP1]], ptr [[VARET]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[VARET]], align 4 +// CHECK-NEXT: ret i32 [[TMP2]] +// int get_int(va_list *args) { return va_arg(*args, int); } +enum RGB { R = 1, G = 2, B = 3 }; + +// CHECK-LABEL: define dso_local i32 @get_enum( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[VARET:%.*]] = alloca i32, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], i32 +// CHECK-NEXT: store i32 [[TMP1]], ptr [[VARET]], align 4 +// CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[VARET]], align 4 +// CHECK-NEXT: ret i32 [[TMP2]] +// +enum RGB get_enum(va_list *args) { + return va_arg(*args, enum RGB); +} + +// CHECK-LABEL: define dso_local i64 @get_long_long( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[VARET:%.*]] = alloca i64, align 8 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], i64 +// CHECK-NEXT: store i64 [[TMP1]], ptr [[VARET]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[VARET]], align 8 +// CHECK-NEXT: ret i64 [[TMP2]] +// +long long get_long_long(va_list *args) { + return va_arg(*args, long long); +} + struct Foo { - int x; + long long x; }; -struct Foo dest; +// CHECK-LABEL: define dso_local void @get_struct( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret([[STRUCT_FOO:%.*]]) align 8 [[AGG_RESULT:%.*]], ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// CHECK-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 8 [[AGG_RESULT]], ptr align 8 [[TMP1]], i32 8, i1 false) +// CHECK-NEXT: ret void +// +struct Foo get_struct(va_list *args) { + return va_arg(*args, struct Foo); +} + +// CHECK-LABEL: define dso_local void @get_long_double( +// CHECK-SAME: ptr dead_on_unwind noalias writable sret(fp128) align 8 [[AGG_RESULT:%.*]], ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[RESULT_PTR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: [[VARET:%.*]] = alloca fp128, align 8 +// CHECK-NEXT: store ptr [[AGG_RESULT]], ptr [[RESULT_PTR]], align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], fp128 +// CHECK-NEXT: store fp128 [[TMP1]], ptr [[VARET]], align 8 +// CHECK-NEXT: [[TMP2:%.*]] = load fp128, ptr [[VARET]], align 8 +// CHECK-NEXT: store fp128 [[TMP2]], ptr [[AGG_RESULT]], align 8 +// CHECK-NEXT: [[TMP3:%.*]] = load fp128, ptr [[AGG_RESULT]], align 8 +// CHECK-NEXT: store fp128 [[TMP3]], ptr [[AGG_RESULT]], align 8 +// CHECK-NEXT: ret void +// +long double get_long_double(va_list *args) { + return va_arg(*args, long double); +} + +_Complex char complex_char_sink; -// CHECK-LABEL: define{{.*}} void @get_struct -// CHECK: [[RESULT:%[a-z_0-9]+]] = va_arg {{.*}}, ptr{{$}} -// CHECK: call void @llvm.memcpy{{.*}}@dest{{.*}}, ptr align {{[0-9]+}} [[RESULT]] -void get_struct(va_list *args) { - dest = va_arg(*args, struct Foo); +// CHECK-LABEL: define dso_local void @get_complex_char( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// CHECK-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[DOTREAL:%.*]] = load i8, ptr [[DOTREALP]], align 1 +// CHECK-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 1 +// CHECK-NEXT: [[DOTIMAG:%.*]] = load i8, ptr [[DOTIMAGP]], align 1 +// CHECK-NEXT: store i8 [[DOTREAL]], ptr @complex_char_sink, align 1 +// CHECK-NEXT: store i8 [[DOTIMAG]], ptr getelementptr inbounds nuw (i8, ptr @complex_char_sink, i32 1), align 1 +// CHECK-NEXT: ret void +// +void get_complex_char(va_list *args) { + complex_char_sink = va_arg(*args, _Complex char); } -enum E { Foo_one = 1 }; +_Complex int complex_int_sink; + +// CHECK-LABEL: define dso_local void @get_complex_int( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// CHECK-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[DOTREAL:%.*]] = load i32, ptr [[DOTREALP]], align 4 +// CHECK-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[TMP1]], i32 0, i32 1 +// CHECK-NEXT: [[DOTIMAG:%.*]] = load i32, ptr [[DOTIMAGP]], align 4 +// CHECK-NEXT: store i32 [[DOTREAL]], ptr @complex_int_sink, align 4 +// CHECK-NEXT: store i32 [[DOTIMAG]], ptr getelementptr inbounds nuw (i8, ptr @complex_int_sink, i32 4), align 4 +// CHECK-NEXT: ret void +// +void get_complex_int(va_list *args) { + complex_int_sink = va_arg(*args, _Complex int); +} + +_Complex long long complex_long_long_sink; + +// CHECK-LABEL: define dso_local void @get_complex_long_long( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// CHECK-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[DOTREAL:%.*]] = load i64, ptr [[DOTREALP]], align 8 +// CHECK-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i64, i64 }, ptr [[TMP1]], i32 0, i32 1 +// CHECK-NEXT: [[DOTIMAG:%.*]] = load i64, ptr [[DOTIMAGP]], align 8 +// CHECK-NEXT: store i64 [[DOTREAL]], ptr @complex_long_long_sink, align 8 +// CHECK-NEXT: store i64 [[DOTIMAG]], ptr getelementptr inbounds nuw (i8, ptr @complex_long_long_sink, i32 8), align 8 +// CHECK-NEXT: ret void +// +void get_complex_long_long (va_list *args) { + complex_long_long_sink = va_arg(*args, _Complex long long ); +} -enum E enum_dest; +_Complex long double complex_long_double_sink; -// CHECK-LABEL: define{{.*}} void @get_enum -// CHECK: va_arg ptr {{.*}}, i32 -void get_enum(va_list *args) { - enum_dest = va_arg(*args, enum E); +// CHECK-LABEL: define dso_local void @get_complex_long_double( +// CHECK-SAME: ptr noundef [[ARGS:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[ARGS_ADDR:%.*]] = alloca ptr, align 4 +// CHECK-NEXT: store ptr [[ARGS]], ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARGS_ADDR]], align 4 +// CHECK-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// CHECK-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { fp128, fp128 }, ptr [[TMP1]], i32 0, i32 0 +// CHECK-NEXT: [[DOTREAL:%.*]] = load fp128, ptr [[DOTREALP]], align 8 +// CHECK-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { fp128, fp128 }, ptr [[TMP1]], i32 0, i32 1 +// CHECK-NEXT: [[DOTIMAG:%.*]] = load fp128, ptr [[DOTIMAGP]], align 8 +// CHECK-NEXT: store fp128 [[DOTREAL]], ptr @complex_long_double_sink, align 8 +// CHECK-NEXT: store fp128 [[DOTIMAG]], ptr getelementptr inbounds nuw (i8, ptr @complex_long_double_sink, i32 16), align 8 +// CHECK-NEXT: ret void +// +void get_complex_long_double(va_list *args) { + complex_long_double_sink = va_arg(*args, _Complex long double); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
