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 10 // CHECK: define void @test1(i32 signext %x, %struct.test1* byval align 8 %y) 11 void test1 (int x, struct test1 y) 12 { 13 } 14 15 // CHECK: define void @test2(i32 signext %x, %struct.test2* byval align 16 %y) 16 void 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 24 void test3 (int x, struct test3 y) 25 { 26 } 27 28 // CHECK: define void @test4(i32 signext %x, %struct.test4* byval align 8 %y) 29 void 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* 38 struct 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* 57 struct 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* 76 struct 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* 91 struct 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* 106 struct test_longdouble { long double x; }; 107 struct 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* 126 struct test_vector { vector int x; }; 127 struct 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