blob: 6a04d0cd84f37d8549c5cc5a5c8fef2191fba03e [file] [log] [blame]
Ulrich Weigand581badc2014-07-10 17:20:07 +00001// RUN: %clang_cc1 -faltivec -triple powerpc64-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
Ulrich Weigand581badc2014-07-10 17:20:07 +00002
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; };
Ulrich Weigand601957f2014-07-21 00:56:36 +00009struct test5 { int x[17]; };
10struct test6 { int x[17]; } __attribute__((aligned (16)));
11struct test7 { int x[17]; } __attribute__((aligned (32)));
Ulrich Weigand581badc2014-07-10 17:20:07 +000012
Ulrich Weigand601957f2014-07-21 00:56:36 +000013// CHECK: define void @test1(i32 signext %x, i64 %y.coerce)
Ulrich Weigand581badc2014-07-10 17:20:07 +000014void test1 (int x, struct test1 y)
15{
16}
17
Ulrich Weigand601957f2014-07-21 00:56:36 +000018// CHECK: define void @test2(i32 signext %x, [1 x i128] %y.coerce)
Ulrich Weigand581badc2014-07-10 17:20:07 +000019void test2 (int x, struct test2 y)
20{
21}
22
Ulrich Weigand601957f2014-07-21 00:56:36 +000023// CHECK: define void @test3(i32 signext %x, [2 x i128] %y.coerce)
Ulrich Weigand581badc2014-07-10 17:20:07 +000024void test3 (int x, struct test3 y)
25{
26}
27
Ulrich Weigand601957f2014-07-21 00:56:36 +000028// CHECK: define void @test4(i32 signext %x, [2 x i64] %y.coerce)
Ulrich Weigand581badc2014-07-10 17:20:07 +000029void test4 (int x, struct test4 y)
30{
31}
32
Ulrich Weigand601957f2014-07-21 00:56:36 +000033// CHECK: define void @test5(i32 signext %x, %struct.test5* byval align 8 %y)
34void test5 (int x, struct test5 y)
35{
36}
37
38// CHECK: define void @test6(i32 signext %x, %struct.test6* byval align 16 %y)
39void test6 (int x, struct test6 y)
40{
41}
42
43// This case requires run-time realignment of the incoming struct
John McCall7f416cc2015-09-08 08:05:57 +000044// CHECK-LABEL: define void @test7(i32 signext %x, %struct.test7* byval align 16)
Ulrich Weigand601957f2014-07-21 00:56:36 +000045// CHECK: %y = alloca %struct.test7, align 32
46// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64
47void test7 (int x, struct test7 y)
48{
49}
50
John McCall7f416cc2015-09-08 08:05:57 +000051// CHECK-LABEL: define void @test1va(%struct.test1* noalias sret %agg.result, i32 signext %x, ...)
52// CHECK: %y = alloca %struct.test1, align 4
David Blaikiea953f282015-02-27 21:19:58 +000053// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +000054// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 8
Ulrich Weigandb4153252014-07-10 19:19:03 +000055// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +000056// CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test1*
57// CHECK: [[DEST:%.*]] = bitcast %struct.test1* %y to i8*
58// CHECK: [[SRC:%.*]] = bitcast %struct.test1* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +000059// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 8, i32 4, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +000060struct test1 test1va (int x, ...)
61{
62 struct test1 y;
63 va_list ap;
64 va_start(ap, x);
65 y = va_arg (ap, struct test1);
66 va_end(ap);
67 return y;
68}
69
John McCall7f416cc2015-09-08 08:05:57 +000070// CHECK-LABEL: define void @test2va(%struct.test2* noalias sret %agg.result, i32 signext %x, ...)
71// CHECK: %y = alloca %struct.test2, align 16
David Blaikiea953f282015-02-27 21:19:58 +000072// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
Ulrich Weigandb4153252014-07-10 19:19:03 +000073// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
74// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
75// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
76// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
John McCall7f416cc2015-09-08 08:05:57 +000077// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 16
Ulrich Weigandb4153252014-07-10 19:19:03 +000078// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +000079// CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test2*
80// CHECK: [[DEST:%.*]] = bitcast %struct.test2* %y to i8*
81// CHECK: [[SRC:%.*]] = bitcast %struct.test2* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +000082// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 16, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +000083struct test2 test2va (int x, ...)
84{
85 struct test2 y;
86 va_list ap;
87 va_start(ap, x);
88 y = va_arg (ap, struct test2);
89 va_end(ap);
90 return y;
91}
92
John McCall7f416cc2015-09-08 08:05:57 +000093// CHECK-LABEL: define void @test3va(%struct.test3* noalias sret %agg.result, i32 signext %x, ...)
94// CHECK: %y = alloca %struct.test3, align 32
David Blaikiea953f282015-02-27 21:19:58 +000095// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
Ulrich Weigandb4153252014-07-10 19:19:03 +000096// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
97// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
98// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
99// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
John McCall7f416cc2015-09-08 08:05:57 +0000100// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 32
Ulrich Weigandb4153252014-07-10 19:19:03 +0000101// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000102// CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test3*
103// CHECK: [[DEST:%.*]] = bitcast %struct.test3* %y to i8*
104// CHECK: [[SRC:%.*]] = bitcast %struct.test3* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +0000105// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 32, i32 16, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +0000106struct test3 test3va (int x, ...)
107{
108 struct test3 y;
109 va_list ap;
110 va_start(ap, x);
111 y = va_arg (ap, struct test3);
112 va_end(ap);
113 return y;
114}
115
John McCall7f416cc2015-09-08 08:05:57 +0000116// CHECK-LABEL: define void @test4va(%struct.test4* noalias sret %agg.result, i32 signext %x, ...)
117// CHECK: %y = alloca %struct.test4, align 4
David Blaikiea953f282015-02-27 21:19:58 +0000118// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000119// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
Ulrich Weigandb4153252014-07-10 19:19:03 +0000120// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000121// CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test4*
122// CHECK: [[DEST:%.*]] = bitcast %struct.test4* %y to i8*
123// CHECK: [[SRC:%.*]] = bitcast %struct.test4* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +0000124// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 12, i32 4, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +0000125struct test4 test4va (int x, ...)
126{
127 struct test4 y;
128 va_list ap;
129 va_start(ap, x);
130 y = va_arg (ap, struct test4);
131 va_end(ap);
132 return y;
133}
134
John McCall7f416cc2015-09-08 08:05:57 +0000135// CHECK-LABEL: define void @testva_longdouble(%struct.test_longdouble* noalias sret %agg.result, i32 signext %x, ...)
136// CHECK: %y = alloca %struct.test_longdouble, align 16
David Blaikiea953f282015-02-27 21:19:58 +0000137// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000138// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[CUR]], i64 16
Ulrich Weigandb4153252014-07-10 19:19:03 +0000139// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000140// CHECK: [[T0:%.*]] = bitcast i8* %[[CUR]] to %struct.test_longdouble*
141// CHECK: [[DEST:%.*]] = bitcast %struct.test_longdouble* %y to i8*
142// CHECK: [[SRC:%.*]] = bitcast %struct.test_longdouble* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +0000143// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 8, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +0000144struct test_longdouble { long double x; };
145struct test_longdouble testva_longdouble (int x, ...)
146{
147 struct test_longdouble y;
148 va_list ap;
149 va_start(ap, x);
150 y = va_arg (ap, struct test_longdouble);
151 va_end(ap);
152 return y;
153}
154
John McCall7f416cc2015-09-08 08:05:57 +0000155// CHECK-LABEL: define void @testva_vector(%struct.test_vector* noalias sret %agg.result, i32 signext %x, ...)
156// CHECK: %y = alloca %struct.test_vector, align 16
David Blaikiea953f282015-02-27 21:19:58 +0000157// CHECK: %[[CUR:[^ ]+]] = load i8*, i8** %ap
Ulrich Weigandb4153252014-07-10 19:19:03 +0000158// CHECK: %[[TMP0:[^ ]+]] = ptrtoint i8* %[[CUR]] to i64
159// CHECK: %[[TMP1:[^ ]+]] = add i64 %[[TMP0]], 15
160// CHECK: %[[TMP2:[^ ]+]] = and i64 %[[TMP1]], -16
161// CHECK: %[[ALIGN:[^ ]+]] = inttoptr i64 %[[TMP2]] to i8*
John McCall7f416cc2015-09-08 08:05:57 +0000162// CHECK: %[[NEXT:[^ ]+]] = getelementptr inbounds i8, i8* %[[ALIGN]], i64 16
Ulrich Weigandb4153252014-07-10 19:19:03 +0000163// CHECK: store i8* %[[NEXT]], i8** %ap
John McCall7f416cc2015-09-08 08:05:57 +0000164// CHECK: [[T0:%.*]] = bitcast i8* %[[ALIGN]] to %struct.test_vector*
165// CHECK: [[DEST:%.*]] = bitcast %struct.test_vector* %y to i8*
166// CHECK: [[SRC:%.*]] = bitcast %struct.test_vector* [[T0]] to i8*
Pete Cooper3b39e882015-11-19 05:55:59 +0000167// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[DEST]], i8* [[SRC]], i64 16, i32 16, i1 false)
Ulrich Weigand581badc2014-07-10 17:20:07 +0000168struct test_vector { vector int x; };
169struct test_vector testva_vector (int x, ...)
170{
171 struct test_vector y;
172 va_list ap;
173 va_start(ap, x);
174 y = va_arg (ap, struct test_vector);
175 va_end(ap);
176 return y;
177}
178