1*67e74705SXin Li // RUN: %clang_cc1 -triple mipsel-unknown-linux -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
2*67e74705SXin Li // RUN: %clang_cc1 -triple mips64el-unknown-linux -O3 -S -target-abi n64 -o - -emit-llvm %s | FileCheck %s -check-prefix=N64
3*67e74705SXin Li // RUN: %clang_cc1 -triple mipsel-unknown-linux -target-feature "+fp64" -O3 -S -o - -emit-llvm %s | FileCheck %s -check-prefix=O32
4*67e74705SXin Li
5*67e74705SXin Li typedef struct {
6*67e74705SXin Li double d;
7*67e74705SXin Li long double ld;
8*67e74705SXin Li } S0;
9*67e74705SXin Li
10*67e74705SXin Li // Insert padding to ensure arguments of type S0 are aligned to 16-byte boundaries.
11*67e74705SXin Li
12*67e74705SXin Li // N64-LABEL: define void @foo1(i32 signext %a0, i64, double inreg %a1.coerce0, i64 inreg %a1.coerce1, i64 inreg %a1.coerce2, i64 inreg %a1.coerce3, double inreg %a2.coerce0, i64 inreg %a2.coerce1, i64 inreg %a2.coerce2, i64 inreg %a2.coerce3, i32 signext %b, i64, double inreg %a3.coerce0, i64 inreg %a3.coerce1, i64 inreg %a3.coerce2, i64 inreg %a3.coerce3)
13*67e74705SXin Li // N64: tail call void @foo2(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, double inreg %a1.coerce0, i64 inreg %a1.coerce1, i64 inreg %a1.coerce2, i64 inreg %a1.coerce3, double inreg %a2.coerce0, i64 inreg %a2.coerce1, i64 inreg %a2.coerce2, i64 inreg %a2.coerce3, i32 signext 3, i64 undef, double inreg %a3.coerce0, i64 inreg %a3.coerce1, i64 inreg %a3.coerce2, i64 inreg %a3.coerce3)
14*67e74705SXin Li // N64: declare void @foo2(i32 signext, i32 signext, i32 signext, i64, double inreg, i64 inreg, i64 inreg, i64 inreg, double inreg, i64 inreg, i64 inreg, i64 inreg, i32 signext, i64, double inreg, i64 inreg, i64 inreg, i64 inreg)
15*67e74705SXin Li
16*67e74705SXin Li extern void foo2(int, int, int, S0, S0, int, S0);
17*67e74705SXin Li
foo1(int a0,S0 a1,S0 a2,int b,S0 a3)18*67e74705SXin Li void foo1(int a0, S0 a1, S0 a2, int b, S0 a3) {
19*67e74705SXin Li foo2(1, 2, a0, a1, a2, 3, a3);
20*67e74705SXin Li }
21*67e74705SXin Li
22*67e74705SXin Li // Insert padding before long double argument.
23*67e74705SXin Li //
24*67e74705SXin Li // N64-LABEL: define void @foo3(i32 signext %a0, i64, fp128 %a1)
25*67e74705SXin Li // N64: tail call void @foo4(i32 signext 1, i32 signext 2, i32 signext %a0, i64 undef, fp128 %a1)
26*67e74705SXin Li // N64: declare void @foo4(i32 signext, i32 signext, i32 signext, i64, fp128)
27*67e74705SXin Li
28*67e74705SXin Li extern void foo4(int, int, int, long double);
29*67e74705SXin Li
foo3(int a0,long double a1)30*67e74705SXin Li void foo3(int a0, long double a1) {
31*67e74705SXin Li foo4(1, 2, a0, a1);
32*67e74705SXin Li }
33*67e74705SXin Li
34*67e74705SXin Li // Insert padding after hidden argument.
35*67e74705SXin Li //
36*67e74705SXin Li // N64-LABEL: define void @foo5(%struct.S0* noalias sret %agg.result, i64, fp128 %a0)
37*67e74705SXin Li // N64: call void @foo6(%struct.S0* sret %agg.result, i32 signext 1, i32 signext 2, i64 undef, fp128 %a0)
38*67e74705SXin Li // N64: declare void @foo6(%struct.S0* sret, i32 signext, i32 signext, i64, fp128)
39*67e74705SXin Li
40*67e74705SXin Li extern S0 foo6(int, int, long double);
41*67e74705SXin Li
foo5(long double a0)42*67e74705SXin Li S0 foo5(long double a0) {
43*67e74705SXin Li return foo6(1, 2, a0);
44*67e74705SXin Li }
45*67e74705SXin Li
46*67e74705SXin Li // Do not insert padding if ABI is O32.
47*67e74705SXin Li //
48*67e74705SXin Li // O32-LABEL: define void @foo7(float %a0, double %a1)
49*67e74705SXin Li // O32: declare void @foo8(float, double)
50*67e74705SXin Li
51*67e74705SXin Li extern void foo8(float, double);
52*67e74705SXin Li
foo7(float a0,double a1)53*67e74705SXin Li void foo7(float a0, double a1) {
54*67e74705SXin Li foo8(a0 + 1.0f, a1 + 2.0);
55*67e74705SXin Li }
56*67e74705SXin Li
57*67e74705SXin Li // O32-LABEL: define void @foo9()
58*67e74705SXin Li // O32: declare void @foo10(i32 signext, i32
59*67e74705SXin Li
60*67e74705SXin Li typedef struct __attribute__((aligned(16))) {
61*67e74705SXin Li int a;
62*67e74705SXin Li } S16;
63*67e74705SXin Li
64*67e74705SXin Li S16 s16;
65*67e74705SXin Li
66*67e74705SXin Li void foo10(int, S16);
67*67e74705SXin Li
foo9(void)68*67e74705SXin Li void foo9(void) {
69*67e74705SXin Li foo10(1, s16);
70*67e74705SXin Li }
71*67e74705SXin Li
72