llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Folkert de Vries (folkertdev) <details> <summary>Changes</summary> equivalent of https://github.com/llvm/llvm-project/pull/216509 for sparc. It similarly has some bugs passing aggregates with floats. --- Patch is 64.45 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/216521.diff 1 Files Affected: - (added) clang/test/CodeGen/Sparc/variadic-aggregate.c (+1015) ``````````diff diff --git a/clang/test/CodeGen/Sparc/variadic-aggregate.c b/clang/test/CodeGen/Sparc/variadic-aggregate.c new file mode 100644 index 0000000000000..92093e1133b8a --- /dev/null +++ b/clang/test/CodeGen/Sparc/variadic-aggregate.c @@ -0,0 +1,1015 @@ +// 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 \ +// RUN: | FileCheck %s --check-prefixes=SPARC +// +// RUN: %clang_cc1 -triple sparcv9-unknown-unknown -emit-llvm -o - %s \ +// RUN: | FileCheck %s --check-prefixes=SPARC64 + +#include <stdarg.h> + +extern void sink(int, ...); + +struct char_char { + char x, y; +}; + +struct short_short { + short x, y; +}; + +struct int_int { + int x, y; +}; + +struct long_long { + long x, y; +}; + +struct long_long_long_long { + long long x, y; +}; + +struct float_float { + float x, y; +}; + +struct double_double { + double x, y; +}; + +struct long_double_long_double { + long double x, y; +}; + +struct aligned_int { + int x; +} __attribute__((aligned(16))); + +struct aligned_float { + float x; +} __attribute__((aligned(16))); + +struct int_int_int_int { + int a, b, c, d; +}; + +struct float_float_float_float { + float a, b, c, d; +}; + +// SPARC-LABEL: define dso_local void @test_complex_char( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca { i8, i8 }, align 1 +// SPARC-NEXT: [[COERCE:%.*]] = alloca { i8, i8 }, align 1 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 0 +// SPARC-NEXT: [[DOTREAL:%.*]] = load i8, ptr [[DOTREALP]], align 1 +// SPARC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 1 +// SPARC-NEXT: [[DOTIMAG:%.*]] = load i8, ptr [[DOTIMAGP]], align 1 +// SPARC-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: store i8 [[DOTREAL]], ptr [[X_REALP]], align 1 +// SPARC-NEXT: store i8 [[DOTIMAG]], ptr [[X_IMAGP]], align 1 +// SPARC-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1 +// SPARC-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1 +// SPARC-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC-NEXT: store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1 +// SPARC-NEXT: store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1 +// SPARC-NEXT: [[TMP2:%.*]] = load i16, ptr [[COERCE]], align 1 +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, i16 noundef [[TMP2]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_complex_char( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca { i8, i8 }, align 1 +// SPARC64-NEXT: [[COERCE:%.*]] = alloca { i8, i8 }, align 1 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 6 +// SPARC64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 0 +// SPARC64-NEXT: [[DOTREAL:%.*]] = load i8, ptr [[DOTREALP]], align 2 +// SPARC64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[TMP1]], i32 0, i32 1 +// SPARC64-NEXT: [[DOTIMAG:%.*]] = load i8, ptr [[DOTIMAGP]], align 1 +// SPARC64-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: store i8 [[DOTREAL]], ptr [[X_REALP]], align 1 +// SPARC64-NEXT: store i8 [[DOTIMAG]], ptr [[X_IMAGP]], align 1 +// SPARC64-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1 +// SPARC64-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1 +// SPARC64-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC64-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC64-NEXT: store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1 +// SPARC64-NEXT: store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1 +// SPARC64-NEXT: [[TMP2:%.*]] = load i16, ptr [[COERCE]], align 1 +// SPARC64-NEXT: call void (i32, ...) @sink(i32 noundef signext 0, i16 noundef [[TMP2]]) +// SPARC64-NEXT: ret void +// +void test_complex_char(va_list *ap) { + _Complex char x = va_arg(*ap, _Complex char); + sink(0, x); +} + +// SPARC-LABEL: define dso_local void @test_char_char( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[X]], ptr align 1 [[TMP1]], i32 2, i1 false) +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, ptr noundef byval([[STRUCT_CHAR_CHAR]]) align 1 [[X]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_char_char( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1 +// SPARC64-NEXT: [[X_COERCE:%.*]] = alloca i64, align 8 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[X]], ptr align 8 [[ARGP_CUR]], i64 2, i1 false) +// SPARC64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[X_COERCE]], ptr align 1 [[X]], i64 2, i1 false) +// SPARC64-NEXT: [[TMP1:%.*]] = load i64, ptr [[X_COERCE]], align 8 +// SPARC64-NEXT: call void (i32, ...) @sink(i32 noundef signext 0, i64 [[TMP1]]) +// SPARC64-NEXT: ret void +// +void test_char_char(va_list *ap) { + struct char_char x = va_arg(*ap, struct char_char); + sink(0, x); +} + +// SPARC-LABEL: define dso_local void @test_complex_short( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca { i16, i16 }, align 2 +// SPARC-NEXT: [[COERCE:%.*]] = alloca { i16, i16 }, align 2 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[TMP1]], i32 0, i32 0 +// SPARC-NEXT: [[DOTREAL:%.*]] = load i16, ptr [[DOTREALP]], align 2 +// SPARC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[TMP1]], i32 0, i32 1 +// SPARC-NEXT: [[DOTIMAG:%.*]] = load i16, ptr [[DOTIMAGP]], align 2 +// SPARC-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: store i16 [[DOTREAL]], ptr [[X_REALP]], align 2 +// SPARC-NEXT: store i16 [[DOTIMAG]], ptr [[X_IMAGP]], align 2 +// SPARC-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_REAL:%.*]] = load i16, ptr [[X_REALP1]], align 2 +// SPARC-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: [[X_IMAG:%.*]] = load i16, ptr [[X_IMAGP2]], align 2 +// SPARC-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC-NEXT: store i16 [[X_REAL]], ptr [[COERCE_REALP]], align 2 +// SPARC-NEXT: store i16 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 2 +// SPARC-NEXT: [[TMP2:%.*]] = load i32, ptr [[COERCE]], align 2 +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, i32 noundef [[TMP2]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_complex_short( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca { i16, i16 }, align 2 +// SPARC64-NEXT: [[COERCE:%.*]] = alloca { i16, i16 }, align 2 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[TMP1:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 4 +// SPARC64-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[TMP1]], i32 0, i32 0 +// SPARC64-NEXT: [[DOTREAL:%.*]] = load i16, ptr [[DOTREALP]], align 4 +// SPARC64-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[TMP1]], i32 0, i32 1 +// SPARC64-NEXT: [[DOTIMAG:%.*]] = load i16, ptr [[DOTIMAGP]], align 2 +// SPARC64-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: store i16 [[DOTREAL]], ptr [[X_REALP]], align 2 +// SPARC64-NEXT: store i16 [[DOTIMAG]], ptr [[X_IMAGP]], align 2 +// SPARC64-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_REAL:%.*]] = load i16, ptr [[X_REALP1]], align 2 +// SPARC64-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: [[X_IMAG:%.*]] = load i16, ptr [[X_IMAGP2]], align 2 +// SPARC64-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC64-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC64-NEXT: store i16 [[X_REAL]], ptr [[COERCE_REALP]], align 2 +// SPARC64-NEXT: store i16 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 2 +// SPARC64-NEXT: [[TMP2:%.*]] = load i32, ptr [[COERCE]], align 2 +// SPARC64-NEXT: call void (i32, ...) @sink(i32 noundef signext 0, i32 noundef [[TMP2]]) +// SPARC64-NEXT: ret void +// +void test_complex_short(va_list *ap) { + _Complex short x = va_arg(*ap, _Complex short); + sink(0, x); +} + +// SPARC-LABEL: define dso_local void @test_short_short( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca [[STRUCT_SHORT_SHORT:%.*]], align 2 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 2 [[X]], ptr align 2 [[TMP1]], i32 4, i1 false) +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, ptr noundef byval([[STRUCT_SHORT_SHORT]]) align 2 [[X]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_short_short( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca [[STRUCT_SHORT_SHORT:%.*]], align 2 +// SPARC64-NEXT: [[X_COERCE:%.*]] = alloca i64, align 8 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 2 [[X]], ptr align 8 [[ARGP_CUR]], i64 4, i1 false) +// SPARC64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[X_COERCE]], ptr align 2 [[X]], i64 4, i1 false) +// SPARC64-NEXT: [[TMP1:%.*]] = load i64, ptr [[X_COERCE]], align 8 +// SPARC64-NEXT: call void (i32, ...) @sink(i32 noundef signext 0, i64 [[TMP1]]) +// SPARC64-NEXT: ret void +// +void test_short_short(va_list *ap) { + struct short_short x = va_arg(*ap, struct short_short); + sink(0, x); +} + +// SPARC-LABEL: define dso_local void @test_complex_int( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca { i32, i32 }, align 4 +// SPARC-NEXT: [[COERCE:%.*]] = alloca { i32, i32 }, align 4 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: [[DOTREALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[TMP1]], i32 0, i32 0 +// SPARC-NEXT: [[DOTREAL:%.*]] = load i32, ptr [[DOTREALP]], align 4 +// SPARC-NEXT: [[DOTIMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[TMP1]], i32 0, i32 1 +// SPARC-NEXT: [[DOTIMAG:%.*]] = load i32, ptr [[DOTIMAGP]], align 4 +// SPARC-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: store i32 [[DOTREAL]], ptr [[X_REALP]], align 4 +// SPARC-NEXT: store i32 [[DOTIMAG]], ptr [[X_IMAGP]], align 4 +// SPARC-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 0 +// SPARC-NEXT: [[X_REAL:%.*]] = load i32, ptr [[X_REALP1]], align 4 +// SPARC-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 1 +// SPARC-NEXT: [[X_IMAG:%.*]] = load i32, ptr [[X_IMAGP2]], align 4 +// SPARC-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC-NEXT: store i32 [[X_REAL]], ptr [[COERCE_REALP]], align 4 +// SPARC-NEXT: store i32 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 4 +// SPARC-NEXT: [[TMP2:%.*]] = load i64, ptr [[COERCE]], align 4 +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, i64 noundef [[TMP2]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_complex_int( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca { i32, i32 }, align 4 +// SPARC64-NEXT: [[COERCE:%.*]] = alloca { i32, i32 }, align 4 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[ARGP_CUR]], i32 0, i32 0 +// SPARC64-NEXT: [[ARGP_CUR_REAL:%.*]] = load i32, ptr [[ARGP_CUR_REALP]], align 8 +// SPARC64-NEXT: [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[ARGP_CUR]], i32 0, i32 1 +// SPARC64-NEXT: [[ARGP_CUR_IMAG:%.*]] = load i32, ptr [[ARGP_CUR_IMAGP]], align 4 +// SPARC64-NEXT: [[X_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: store i32 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 4 +// SPARC64-NEXT: store i32 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 4 +// SPARC64-NEXT: [[X_REALP1:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 0 +// SPARC64-NEXT: [[X_REAL:%.*]] = load i32, ptr [[X_REALP1]], align 4 +// SPARC64-NEXT: [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[X]], i32 0, i32 1 +// SPARC64-NEXT: [[X_IMAG:%.*]] = load i32, ptr [[X_IMAGP2]], align 4 +// SPARC64-NEXT: [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[COERCE]], i32 0, i32 0 +// SPARC64-NEXT: [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i32, i32 }, ptr [[COERCE]], i32 0, i32 1 +// SPARC64-NEXT: store i32 [[X_REAL]], ptr [[COERCE_REALP]], align 4 +// SPARC64-NEXT: store i32 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 4 +// SPARC64-NEXT: [[TMP1:%.*]] = load i64, ptr [[COERCE]], align 4 +// SPARC64-NEXT: call void (i32, ...) @sink(i32 noundef signext 0, i64 noundef [[TMP1]]) +// SPARC64-NEXT: ret void +// +void test_complex_int(va_list *ap) { + _Complex int x = va_arg(*ap, _Complex int); + sink(0, x); +} + +// SPARC-LABEL: define dso_local void @test_int_int( +// SPARC-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC-NEXT: [[ENTRY:.*:]] +// SPARC-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 4 +// SPARC-NEXT: [[X:%.*]] = alloca [[STRUCT_INT_INT:%.*]], align 4 +// SPARC-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4 +// SPARC-NEXT: [[TMP1:%.*]] = va_arg ptr [[TMP0]], ptr +// SPARC-NEXT: call void @llvm.memcpy.p0.p0.i32(ptr align 4 [[X]], ptr align 4 [[TMP1]], i32 8, i1 false) +// SPARC-NEXT: call void (i32, ...) @sink(i32 noundef 0, ptr noundef byval([[STRUCT_INT_INT]]) align 4 [[X]]) +// SPARC-NEXT: ret void +// +// SPARC64-LABEL: define dso_local void @test_int_int( +// SPARC64-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] { +// SPARC64-NEXT: [[ENTRY:.*:]] +// SPARC64-NEXT: [[AP_ADDR:%.*]] = alloca ptr, align 8 +// SPARC64-NEXT: [[X:%.*]] = alloca [[STRUCT_INT_INT:%.*]], align 4 +// SPARC64-NEXT: store ptr [[AP]], ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8 +// SPARC64-NEXT: [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8 +// SPARC64-NEXT: [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr [[ARGP_CUR]], i64 8 +// SPARC64-NEXT: store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8 +// SPARC64-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/216521 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
