llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-mips

Author: Folkert de Vries (folkertdev)

<details>
<summary>Changes</summary>

mips64 has some bugs here that I'll address in a followup. The problem is that 
we get `inreg {float}` items in the variable argument list. That breaks for 
aggregates like `_Complex long double` or just `struct { long double a; b }`.

---

Patch is 155.89 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/216509.diff


1 Files Affected:

- (added) clang/test/CodeGen/Mips/variadic-aggregate.c (+2162) 


``````````diff
diff --git a/clang/test/CodeGen/Mips/variadic-aggregate.c 
b/clang/test/CodeGen/Mips/variadic-aggregate.c
new file mode 100644
index 0000000000000..4c72dcb639c1a
--- /dev/null
+++ b/clang/test/CodeGen/Mips/variadic-aggregate.c
@@ -0,0 +1,2162 @@
+// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py 
UTC_ARGS: --version 6
+// RUN: %clang_cc1 -triple mips-none-linux-gnu -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefixes=GPR32,GPR32BE
+// RUN: %clang_cc1 -triple mipsel-none-linux-gnu -emit-llvm -o - %s \
+// RUN:   | FileCheck %s --check-prefixes=GPR32,GPR32LE
+
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -target-abi n32 -emit-llvm -o 
- %s \
+// RUN:   | FileCheck %s --check-prefixes=GPR64N32
+// RUN: %clang_cc1 -triple mips64-none-linux-gnu -target-abi n64 -emit-llvm -o 
- %s \
+// RUN:   | FileCheck %s --check-prefixes=GPR64N64BE
+// RUN: %clang_cc1 -triple mips64el-none-linux-gnu -target-abi n64 -emit-llvm 
-o - %s \
+// RUN:   | FileCheck %s --check-prefixes=GPR64N64LE
+
+// Test mips logic for reading aggregates from the variable argument list.
+
+#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;
+};
+
+// GPR32-LABEL: define dso_local void @test_complex_char(
+// GPR32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] {
+// GPR32-NEXT:  [[ENTRY:.*:]]
+// GPR32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR32-NEXT:    [[X:%.*]] = alloca { i8, i8 }, align 1
+// GPR32-NEXT:    [[COERCE:%.*]] = alloca { i8, i8 }, align 1
+// GPR32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 4
+// GPR32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR32-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR32-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i8, ptr [[ARGP_CUR_REALP]], 
align 4
+// GPR32-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR32-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i8, ptr [[ARGP_CUR_IMAGP]], 
align 1
+// GPR32-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr 
[[X]], i32 0, i32 0
+// GPR32-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, ptr 
[[X]], i32 0, i32 1
+// GPR32-NEXT:    store i8 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 1
+// GPR32-NEXT:    store i8 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 1
+// GPR32-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 0
+// GPR32-NEXT:    [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1
+// GPR32-NEXT:    [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 1
+// GPR32-NEXT:    [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1
+// GPR32-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[COERCE]], i32 0, i32 0
+// GPR32-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[COERCE]], i32 0, i32 1
+// GPR32-NEXT:    store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1
+// GPR32-NEXT:    store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1
+// GPR32-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[COERCE]], i32 0, i32 0
+// GPR32-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR32-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 inreg 
noundef [[TMP2]])
+// GPR32-NEXT:    ret void
+//
+// GPR64N32-LABEL: define dso_local void @test_complex_char(
+// GPR64N32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] {
+// GPR64N32-NEXT:  [[ENTRY:.*:]]
+// GPR64N32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR64N32-NEXT:    [[X:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N32-NEXT:    [[COERCE:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 8
+// GPR64N32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR64N32-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i8, ptr [[ARGP_CUR_REALP]], 
align 8
+// GPR64N32-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR64N32-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i8, ptr [[ARGP_CUR_IMAGP]], 
align 1
+// GPR64N32-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 0
+// GPR64N32-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 1
+// GPR64N32-NEXT:    store i8 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 1
+// GPR64N32-NEXT:    store i8 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 1
+// GPR64N32-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 0
+// GPR64N32-NEXT:    [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1
+// GPR64N32-NEXT:    [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 }, 
ptr [[X]], i32 0, i32 1
+// GPR64N32-NEXT:    [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1
+// GPR64N32-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 0
+// GPR64N32-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 1
+// GPR64N32-NEXT:    store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1
+// GPR64N32-NEXT:    store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1
+// GPR64N32-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[COERCE]], i32 0, i32 0
+// GPR64N32-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N32-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg noundef [[TMP2]])
+// GPR64N32-NEXT:    ret void
+//
+// GPR64N64BE-LABEL: define dso_local void @test_complex_char(
+// GPR64N64BE-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] {
+// GPR64N64BE-NEXT:  [[ENTRY:.*:]]
+// GPR64N64BE-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 8
+// GPR64N64BE-NEXT:    [[X:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N64BE-NEXT:    [[COERCE:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N64BE-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 8
+// GPR64N64BE-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i64 8
+// GPR64N64BE-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { 
i8, i8 }, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i8, ptr 
[[ARGP_CUR_REALP]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { 
i8, i8 }, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR64N64BE-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i8, ptr 
[[ARGP_CUR_IMAGP]], align 1
+// GPR64N64BE-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 1
+// GPR64N64BE-NEXT:    store i8 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 1
+// GPR64N64BE-NEXT:    store i8 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 1
+// GPR64N64BE-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1
+// GPR64N64BE-NEXT:    [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 1
+// GPR64N64BE-NEXT:    [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1
+// GPR64N64BE-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 1
+// GPR64N64BE-NEXT:    store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1
+// GPR64N64BE-NEXT:    store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1
+// GPR64N64BE-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[COERCE]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N64BE-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg noundef [[TMP2]])
+// GPR64N64BE-NEXT:    ret void
+//
+// GPR64N64LE-LABEL: define dso_local void @test_complex_char(
+// GPR64N64LE-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0:[0-9]+]] {
+// GPR64N64LE-NEXT:  [[ENTRY:.*:]]
+// GPR64N64LE-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 8
+// GPR64N64LE-NEXT:    [[X:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N64LE-NEXT:    [[COERCE:%.*]] = alloca { i8, i8 }, align 1
+// GPR64N64LE-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 8
+// GPR64N64LE-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i64 8
+// GPR64N64LE-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { 
i8, i8 }, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i8, ptr 
[[ARGP_CUR_REALP]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { 
i8, i8 }, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR64N64LE-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i8, ptr 
[[ARGP_CUR_IMAGP]], align 1
+// GPR64N64LE-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 1
+// GPR64N64LE-NEXT:    store i8 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 1
+// GPR64N64LE-NEXT:    store i8 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 1
+// GPR64N64LE-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[X_REAL:%.*]] = load i8, ptr [[X_REALP1]], align 1
+// GPR64N64LE-NEXT:    [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i8, i8 
}, ptr [[X]], i32 0, i32 1
+// GPR64N64LE-NEXT:    [[X_IMAG:%.*]] = load i8, ptr [[X_IMAGP2]], align 1
+// GPR64N64LE-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i8, 
i8 }, ptr [[COERCE]], i32 0, i32 1
+// GPR64N64LE-NEXT:    store i8 [[X_REAL]], ptr [[COERCE_REALP]], align 1
+// GPR64N64LE-NEXT:    store i8 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 1
+// GPR64N64LE-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[COERCE]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N64LE-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg noundef [[TMP2]])
+// GPR64N64LE-NEXT:    ret void
+//
+void test_complex_char(va_list *ap) {
+  _Complex char x = va_arg(*ap, _Complex char);
+  sink(0, x);
+}
+
+// GPR32-LABEL: define dso_local void @test_char_char(
+// GPR32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR32-NEXT:  [[ENTRY:.*:]]
+// GPR32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR32-NEXT:    [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1
+// GPR32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 4
+// GPR32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR32-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[X]], ptr 
align 4 [[ARGP_CUR]], i32 2, i1 false)
+// GPR32-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[X]], i32 0, i32 0
+// GPR32-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR32-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 inreg 
[[TMP2]])
+// GPR32-NEXT:    ret void
+//
+// GPR64N32-LABEL: define dso_local void @test_char_char(
+// GPR64N32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR64N32-NEXT:  [[ENTRY:.*:]]
+// GPR64N32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR64N32-NEXT:    [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1
+// GPR64N32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 8
+// GPR64N32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    call void @llvm.memcpy.p0.p0.i32(ptr align 1 [[X]], ptr 
align 8 [[ARGP_CUR]], i32 2, i1 false)
+// GPR64N32-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[X]], i32 0, i32 0
+// GPR64N32-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N32-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg [[TMP2]])
+// GPR64N32-NEXT:    ret void
+//
+// GPR64N64BE-LABEL: define dso_local void @test_char_char(
+// GPR64N64BE-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR64N64BE-NEXT:  [[ENTRY:.*:]]
+// GPR64N64BE-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 8
+// GPR64N64BE-NEXT:    [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1
+// GPR64N64BE-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 8
+// GPR64N64BE-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8
+// GPR64N64BE-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i64 8
+// GPR64N64BE-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8
+// GPR64N64BE-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[X]], ptr 
align 8 [[ARGP_CUR]], i64 2, i1 false)
+// GPR64N64BE-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[X]], i32 0, i32 0
+// GPR64N64BE-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N64BE-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg [[TMP2]])
+// GPR64N64BE-NEXT:    ret void
+//
+// GPR64N64LE-LABEL: define dso_local void @test_char_char(
+// GPR64N64LE-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR64N64LE-NEXT:  [[ENTRY:.*:]]
+// GPR64N64LE-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 8
+// GPR64N64LE-NEXT:    [[X:%.*]] = alloca [[STRUCT_CHAR_CHAR:%.*]], align 1
+// GPR64N64LE-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 8
+// GPR64N64LE-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 8
+// GPR64N64LE-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i64 8
+// GPR64N64LE-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 8
+// GPR64N64LE-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 1 [[X]], ptr 
align 8 [[ARGP_CUR]], i64 2, i1 false)
+// GPR64N64LE-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i16 }, ptr 
[[X]], i32 0, i32 0
+// GPR64N64LE-NEXT:    [[TMP2:%.*]] = load i16, ptr [[TMP1]], align 1
+// GPR64N64LE-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i16 
inreg [[TMP2]])
+// GPR64N64LE-NEXT:    ret void
+//
+void test_char_char(va_list *ap) {
+  struct char_char x = va_arg(*ap, struct char_char);
+  sink(0, x);
+}
+
+// GPR32-LABEL: define dso_local void @test_complex_short(
+// GPR32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR32-NEXT:  [[ENTRY:.*:]]
+// GPR32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR32-NEXT:    [[X:%.*]] = alloca { i16, i16 }, align 2
+// GPR32-NEXT:    [[COERCE:%.*]] = alloca { i16, i16 }, align 2
+// GPR32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 4
+// GPR32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR32-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { i16, 
i16 }, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR32-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i16, ptr [[ARGP_CUR_REALP]], 
align 4
+// GPR32-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { i16, 
i16 }, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR32-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i16, ptr [[ARGP_CUR_IMAGP]], 
align 2
+// GPR32-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 }, 
ptr [[X]], i32 0, i32 0
+// GPR32-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 }, 
ptr [[X]], i32 0, i32 1
+// GPR32-NEXT:    store i16 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 2
+// GPR32-NEXT:    store i16 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 2
+// GPR32-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i16, i16 }, 
ptr [[X]], i32 0, i32 0
+// GPR32-NEXT:    [[X_REAL:%.*]] = load i16, ptr [[X_REALP1]], align 2
+// GPR32-NEXT:    [[X_IMAGP2:%.*]] = getelementptr inbounds nuw { i16, i16 }, 
ptr [[X]], i32 0, i32 1
+// GPR32-NEXT:    [[X_IMAG:%.*]] = load i16, ptr [[X_IMAGP2]], align 2
+// GPR32-NEXT:    [[COERCE_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 
}, ptr [[COERCE]], i32 0, i32 0
+// GPR32-NEXT:    [[COERCE_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 
}, ptr [[COERCE]], i32 0, i32 1
+// GPR32-NEXT:    store i16 [[X_REAL]], ptr [[COERCE_REALP]], align 2
+// GPR32-NEXT:    store i16 [[X_IMAG]], ptr [[COERCE_IMAGP]], align 2
+// GPR32-NEXT:    [[TMP1:%.*]] = getelementptr inbounds nuw { i32 }, ptr 
[[COERCE]], i32 0, i32 0
+// GPR32-NEXT:    [[TMP2:%.*]] = load i32, ptr [[TMP1]], align 2
+// GPR32-NEXT:    call void (i32, ...) @sink(i32 noundef signext 0, i32 inreg 
noundef [[TMP2]])
+// GPR32-NEXT:    ret void
+//
+// GPR64N32-LABEL: define dso_local void @test_complex_short(
+// GPR64N32-SAME: ptr noundef [[AP:%.*]]) #[[ATTR0]] {
+// GPR64N32-NEXT:  [[ENTRY:.*:]]
+// GPR64N32-NEXT:    [[AP_ADDR:%.*]] = alloca ptr, align 4
+// GPR64N32-NEXT:    [[X:%.*]] = alloca { i16, i16 }, align 2
+// GPR64N32-NEXT:    [[COERCE:%.*]] = alloca { i16, i16 }, align 2
+// GPR64N32-NEXT:    store ptr [[AP]], ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[TMP0:%.*]] = load ptr, ptr [[AP_ADDR]], align 4
+// GPR64N32-NEXT:    [[ARGP_CUR:%.*]] = load ptr, ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    [[ARGP_NEXT:%.*]] = getelementptr inbounds i8, ptr 
[[ARGP_CUR]], i32 8
+// GPR64N32-NEXT:    store ptr [[ARGP_NEXT]], ptr [[TMP0]], align 4
+// GPR64N32-NEXT:    [[ARGP_CUR_REALP:%.*]] = getelementptr inbounds nuw { 
i16, i16 }, ptr [[ARGP_CUR]], i32 0, i32 0
+// GPR64N32-NEXT:    [[ARGP_CUR_REAL:%.*]] = load i16, ptr [[ARGP_CUR_REALP]], 
align 8
+// GPR64N32-NEXT:    [[ARGP_CUR_IMAGP:%.*]] = getelementptr inbounds nuw { 
i16, i16 }, ptr [[ARGP_CUR]], i32 0, i32 1
+// GPR64N32-NEXT:    [[ARGP_CUR_IMAG:%.*]] = load i16, ptr [[ARGP_CUR_IMAGP]], 
align 2
+// GPR64N32-NEXT:    [[X_REALP:%.*]] = getelementptr inbounds nuw { i16, i16 
}, ptr [[X]], i32 0, i32 0
+// GPR64N32-NEXT:    [[X_IMAGP:%.*]] = getelementptr inbounds nuw { i16, i16 
}, ptr [[X]], i32 0, i32 1
+// GPR64N32-NEXT:    store i16 [[ARGP_CUR_REAL]], ptr [[X_REALP]], align 2
+// GPR64N32-NEXT:    store i16 [[ARGP_CUR_IMAG]], ptr [[X_IMAGP]], align 2
+// GPR64N32-NEXT:    [[X_REALP1:%.*]] = getelementptr inbounds nuw { i16, i16 
}, ptr [[X]], i32 0, i32 0
+// GPR64N32-NEXT:    [[X_REAL:%.*]] = load i16, ptr [[X_REALP1]], ali...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/216509
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to