Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -triple x86_64-unknown-nacl -emit-llvm -o - %s| FileCheck %s
      2 #include <stdarg.h>
      3 // Test for x86-64 structure representation (instead of pnacl representation),
      4 // in particular for unions. Also crib a few tests from x86 Linux.
      5 
      6 union PP_VarValue {
      7   int as_int;
      8   double as_double;
      9   long long as_i64;
     10 };
     11 
     12 struct PP_Var {
     13   int type;
     14   int padding;
     15   union PP_VarValue value;
     16 };
     17 
     18 // CHECK: define { i64, i64 } @f0()
     19 struct PP_Var f0() {
     20   struct PP_Var result = { 0, 0, 0 };
     21   return result;
     22 }
     23 
     24 // CHECK: define void @f1(i64 %p1.coerce0, i64 %p1.coerce1)
     25 void f1(struct PP_Var p1) { while(1) {} }
     26 
     27 // long doubles are 64 bits on NaCl
     28 // CHECK: define double @f5()
     29 long double f5(void) {
     30   return 0;
     31 }
     32 
     33 // CHECK: define void @f6(i8 signext %a0, i16 signext %a1, i32 %a2, i64 %a3, i8* %a4)
     34 void f6(char a0, short a1, int a2, long long a3, void *a4) {
     35 }
     36 
     37 // CHECK: define i64 @f8_1()
     38 // CHECK: define void @f8_2(i64 %a0.coerce)
     39 union u8 {
     40   long double a;
     41   int b;
     42 };
     43 union u8 f8_1() { while (1) {} }
     44 void f8_2(union u8 a0) {}
     45 
     46 // CHECK: define i64 @f9()
     47 struct s9 { int a; int b; int : 0; } f9(void) { while (1) {} }
     48 
     49 // CHECK: define void @f10(i64 %a0.coerce)
     50 struct s10 { int a; int b; int : 0; };
     51 void f10(struct s10 a0) {}
     52 
     53 // CHECK: define double @f11()
     54 union { long double a; float b; } f11() { while (1) {} }
     55 
     56 // CHECK: define i32 @f12_0()
     57 // CHECK: define void @f12_1(i32 %a0.coerce)
     58 struct s12 { int a __attribute__((aligned(16))); };
     59 struct s12 f12_0(void) { while (1) {} }
     60 void f12_1(struct s12 a0) {}
     61 
     62 // Check that sret parameter is accounted for when checking available integer
     63 // registers.
     64 // CHECK: define void @f13(%struct.s13_0* noalias sret %agg.result, i32 %a, i32 %b, i32 %c, i32 %d, {{.*}}* byval align 8 %e, i32 %f)
     65 
     66 struct s13_0 { long long f0[3]; };
     67 struct s13_1 { long long f0[2]; };
     68 struct s13_0 f13(int a, int b, int c, int d,
     69                  struct s13_1 e, int f) { while (1) {} }
     70 
     71 // CHECK: define void @f20(%struct.s20* byval align 32 %x)
     72 struct __attribute__((aligned(32))) s20 {
     73   int x;
     74   int y;
     75 };
     76 void f20(struct s20 x) {}
     77 
     78 
     79 // CHECK: declare void @func(i64)
     80 typedef struct _str {
     81   union {
     82     long double a;
     83     long c;
     84   };
     85 } str;
     86 
     87 void func(str s);
     88 str ss;
     89 void f9122143()
     90 {
     91   func(ss);
     92 }
     93 
     94 
     95 typedef struct {
     96   int a;
     97   int b;
     98 } s1;
     99 // CHECK: define i32 @f48(%struct.s1* byval %s)
    100 int __attribute__((pnaclcall)) f48(s1 s) { return s.a; }
    101 
    102 // CHECK: define void @f49(%struct.s1* noalias sret %agg.result)
    103 s1 __attribute__((pnaclcall)) f49() { s1 s; s.a = s.b = 1; return s; }
    104 
    105 union simple_union {
    106   int a;
    107   char b;
    108 };
    109 // Unions should be passed as byval structs
    110 // CHECK: define void @f50(%union.simple_union* byval %s)
    111 void __attribute__((pnaclcall)) f50(union simple_union s) {}
    112 
    113 typedef struct {
    114   int b4 : 4;
    115   int b3 : 3;
    116   int b8 : 8;
    117 } bitfield1;
    118 // Bitfields should be passed as byval structs
    119 // CHECK: define void @f51(%struct.bitfield1* byval %bf1)
    120 void __attribute__((pnaclcall)) f51(bitfield1 bf1) {}
    121