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