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