Home | History | Annotate | Download | only in CodeGen
      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