1// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
2
3#include <stdarg.h>
4
5struct test1 { int x; int y; };
6struct test2 { int x; int y; } __attribute__((aligned (16)));
7struct test3 { int x; int y; } __attribute__((aligned (32)));
8struct test4 { int x; int y; int z; };
9
10// CHECK: define void @test1(i32 signext %x, %struct.test1* byval align 8 %y)
11void test1 (int x, struct test1 y)
12{
13}
14
15// CHECK: define void @test2(i32 signext %x, %struct.test2* byval align 16 %y)
16void test2 (int x, struct test2 y)
17{
18}
19
20// This case requires run-time realignment of the incoming struct
21// CHECK: define void @test3(i32 signext %x, %struct.test3* byval align 16)
22// CHECK: %y = alloca %struct.test3, align 32
23// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
24void test3 (int x, struct test3 y)
25{
26}
27
28// CHECK: define void @test4(i32 signext %x, %struct.test4* byval align 8 %y)
29void test4 (int x, struct test4 y)
30{
31}
32
33// CHECK: define void @test1va(%struct.test1* noalias sret %agg.result, i32 signext %x, ...)
34// CHECK: %ap.cur = load i8** %ap
35// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 8
36// CHECK: store i8* %ap.next, i8** %ap
37// CHECK: bitcast i8* %ap.cur to %struct.test1*
38struct test1 test1va (int x, ...)
39{
40  struct test1 y;
41  va_list ap;
42  va_start(ap, x);
43  y = va_arg (ap, struct test1);
44  va_end(ap);
45  return y;
46}
47
48// CHECK: define void @test2va(%struct.test2* noalias sret %agg.result, i32 signext %x, ...)
49// CHECK: %ap.cur = load i8** %ap
50// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
51// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
52// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
53// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
54// CHECK: %ap.next = getelementptr i8* %ap.align, i64 16
55// CHECK: store i8* %ap.next, i8** %ap
56// CHECK: bitcast i8* %ap.align to %struct.test2*
57struct test2 test2va (int x, ...)
58{
59  struct test2 y;
60  va_list ap;
61  va_start(ap, x);
62  y = va_arg (ap, struct test2);
63  va_end(ap);
64  return y;
65}
66
67// CHECK: define void @test3va(%struct.test3* noalias sret %agg.result, i32 signext %x, ...)
68// CHECK: %ap.cur = load i8** %ap
69// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
70// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
71// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
72// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
73// CHECK: %ap.next = getelementptr i8* %ap.align, i64 32
74// CHECK: store i8* %ap.next, i8** %ap
75// CHECK: bitcast i8* %ap.align to %struct.test3*
76struct test3 test3va (int x, ...)
77{
78  struct test3 y;
79  va_list ap;
80  va_start(ap, x);
81  y = va_arg (ap, struct test3);
82  va_end(ap);
83  return y;
84}
85
86// CHECK: define void @test4va(%struct.test4* noalias sret %agg.result, i32 signext %x, ...)
87// CHECK: %ap.cur = load i8** %ap
88// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 16
89// CHECK: store i8* %ap.next, i8** %ap
90// CHECK: bitcast i8* %ap.cur to %struct.test4*
91struct test4 test4va (int x, ...)
92{
93  struct test4 y;
94  va_list ap;
95  va_start(ap, x);
96  y = va_arg (ap, struct test4);
97  va_end(ap);
98  return y;
99}
100
101// CHECK: define void @testva_longdouble(%struct.test_longdouble* noalias sret %agg.result, i32 signext %x, ...)
102// CHECK: %ap.cur = load i8** %ap
103// CHECK: %ap.next = getelementptr i8* %ap.cur, i64 16
104// CHECK: store i8* %ap.next, i8** %ap
105// CHECK: bitcast i8* %ap.cur to %struct.test_longdouble*
106struct test_longdouble { long double x; };
107struct test_longdouble testva_longdouble (int x, ...)
108{
109  struct test_longdouble y;
110  va_list ap;
111  va_start(ap, x);
112  y = va_arg (ap, struct test_longdouble);
113  va_end(ap);
114  return y;
115}
116
117// CHECK: define void @testva_vector(%struct.test_vector* noalias sret %agg.result, i32 signext %x, ...)
118// CHECK: %ap.cur = load i8** %ap
119// CHECK: %[[TMP0:[0-9]+]] = ptrtoint i8* %ap.cur to i64
120// CHECK: %[[TMP1:[0-9]+]] = add i64 %[[TMP0]], 15
121// CHECK: %[[TMP2:[0-9]+]] = and i64 %[[TMP1]], -16
122// CHECK: %ap.align = inttoptr i64 %[[TMP2]] to i8*
123// CHECK: %ap.next = getelementptr i8* %ap.align, i64 16
124// CHECK: store i8* %ap.next, i8** %ap
125// CHECK: bitcast i8* %ap.align to %struct.test_vector*
126struct test_vector { vector int x; };
127struct test_vector testva_vector (int x, ...)
128{
129  struct test_vector y;
130  va_list ap;
131  va_start(ap, x);
132  y = va_arg (ap, struct test_vector);
133  va_end(ap);
134  return y;
135}
136
137