1// RUN: %Slang %s
2
3// RUN: %rs-filecheck-wrapper %s --check-prefix=CHECK-LL
4//
5//     Check that the data types are properly padded:
6//
7// CHECK-LL: %struct.char_struct{{(\.[0-9]+)?}} = type { i16, [6 x i8], i64 }
8// CHECK-LL: %struct.five_struct{{(\.[0-9]+)?}} = type { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }
9//
10//     Check that the helper function for unpacking an invokable's arguments
11//     accesses a properly padded struct:
12//
13// CHECK-LL: define void @.helper_check_char_struct({ i16, [6 x i8], i64 }* nocapture)
14// CHECK-LL: [[C_F1_ADDR:%[0-9]+]] = getelementptr inbounds { i16, [6 x i8], i64 }, { i16, [6 x i8], i64 }* %0, i{{[0-9]+}} 0, i32 0
15// CHECK-LL: [[C_F1_VAL:%[0-9]+]] = load i16, i16* [[C_F1_ADDR]]
16// CHECK-LL: [[C_F2_ADDR:%[0-9]+]] = getelementptr inbounds { i16, [6 x i8], i64 }, { i16, [6 x i8], i64 }* %0, i{{[0-9]+}} 0, i32 2
17// CHECK-LL: [[C_F2_VAL:%[0-9]+]] = load i64, i64* [[C_F2_ADDR]]
18// CHECK-LL: tail call void @check_char_struct(i16 [[C_F1_VAL]], i64 [[C_F2_VAL]])
19//
20// CHECK-LL: define void @.helper_check_five_struct({ i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* nocapture)
21// CHECK-LL: [[F_F1_ADDR:%[0-9]+]] = getelementptr inbounds { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }, { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* %0, i{{[0-9]+}} 0, i32 0
22// CHECK-LL: [[F_F1_VAL:%[0-9]+]] = load i8, i8* [[F_F1_ADDR]]
23// CHECK-LL: [[F_F2_ADDR:%[0-9]+]] = getelementptr inbounds { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }, { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* %0, i{{[0-9]+}} 0, i32 2
24// CHECK-LL: [[F_F2_VAL:%[0-9]+]] = load i64, i64* [[F_F2_ADDR]]
25// CHECK-LL: [[F_F3_ADDR:%[0-9]+]] = getelementptr inbounds { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }, { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* %0, i{{[0-9]+}} 0, i32 3
26// CHECK-LL: [[F_F3_VAL:%[0-9]+]] = load i16, i16* [[F_F3_ADDR]]
27// CHECK-LL: [[F_F4_ADDR:%[0-9]+]] = getelementptr inbounds { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }, { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* %0, i{{[0-9]+}} 0, i32 5
28// CHECK-LL: [[F_F4_VAL:%[0-9]+]] = load i64, i64* [[F_F4_ADDR]]
29// CHECK-LL: [[F_F5_ADDR:%[0-9]+]] = getelementptr inbounds { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }, { i8, [7 x i8], i64, i16, [6 x i8], i64, half, [6 x i8] }* %0, i{{[0-9]+}} 0, i32 6
30// CHECK-LL: [[F_F5_VAL:%[0-9]+]] = load half, half* [[F_F5_ADDR]]
31// CHECK-LL: tail call void @check_five_struct(i8 [[F_F1_VAL]], i64 [[F_F2_VAL]], i16 [[F_F3_VAL]], i64 [[F_F4_VAL]], half [[F_F5_VAL]])
32
33// RUN: %scriptc-filecheck-wrapper --lang=Java --type=char_struct --check-prefix=CHECK-JAVA-CHAR-STRUCT %s
34// CHECK-JAVA-CHAR-STRUCT:      public static Element createElement(RenderScript rs) {
35// CHECK-JAVA-CHAR-STRUCT-NEXT:     Element.Builder eb = new Element.Builder(rs);
36// CHECK-JAVA-CHAR-STRUCT-NEXT:     eb.add(Element.I16(rs), "f1");
37// CHECK-JAVA-CHAR-STRUCT-NEXT:     eb.add(Element.U32(rs), "#rs_padding_1");
38// CHECK-JAVA-CHAR-STRUCT-NEXT:     eb.add(Element.U16(rs), "#rs_padding_2");
39// CHECK-JAVA-CHAR-STRUCT-NEXT:     eb.add(Element.I64(rs), "f2");
40// CHECK-JAVA-CHAR-STRUCT-NEXT:     return eb.create();
41// CHECK-JAVA-CHAR-STRUCT-NEXT: }
42
43// RUN: %scriptc-filecheck-wrapper --lang=Java --type=five_struct --check-prefix=CHECK-JAVA-FIVE-STRUCT %s
44// CHECK-JAVA-FIVE-STRUCT:      public static Element createElement(RenderScript rs) {
45// CHECK-JAVA-FIVE-STRUCT-NEXT:     Element.Builder eb = new Element.Builder(rs);
46// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.I8(rs), "f1");
47// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U32(rs), "#rs_padding_1");
48// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U16(rs), "#rs_padding_2");
49// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U8(rs), "#rs_padding_3");
50// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.I64(rs), "f2");
51// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.I16(rs), "f3");
52// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U32(rs), "#rs_padding_4");
53// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U16(rs), "#rs_padding_5");
54// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.I64(rs), "f4");
55// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.F16(rs), "f5");
56// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U32(rs), "#rs_padding_6");
57// CHECK-JAVA-FIVE-STRUCT-NEXT:     eb.add(Element.U16(rs), "#rs_padding_7");
58// CHECK-JAVA-FIVE-STRUCT-NEXT:     return eb.create();
59// CHECK-JAVA-FIVE-STRUCT-NEXT: }
60
61// RUN: %scriptc-filecheck-wrapper --lang=Java --check-prefix=CHECK-JAVA-INVOKE %s
62//
63// CHECK-JAVA-INVOKE:      public void invoke_check_char_struct(short arg1, long arg2) {
64// CHECK-JAVA-INVOKE-NEXT:     FieldPacker check_char_struct_fp = new FieldPacker(16);
65// CHECK-JAVA-INVOKE-NEXT:     check_char_struct_fp.addI16(arg1);
66// CHECK-JAVA-INVOKE-NEXT:     check_char_struct_fp.skip(6);
67// CHECK-JAVA-INVOKE-NEXT:     check_char_struct_fp.addI64(arg2);
68// CHECK-JAVA-INVOKE-NEXT:     invoke(mExportFuncIdx_check_char_struct, check_char_struct_fp);
69// CHECK-JAVA-INVOKE-NEXT: }
70//
71// CHECK-JAVA-INVOKE:      public void invoke_check_five_struct(byte arg1, long arg2, short arg3, long arg4, short arg5) {
72// CHECK-JAVA-INVOKE-NEXT:     FieldPacker check_five_struct_fp = new FieldPacker(40);
73// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.addI8(arg1);
74// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.skip(7);
75// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.addI64(arg2);
76// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.addI16(arg3);
77// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.skip(6);
78// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.addI64(arg4);
79// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.addI16(arg5);
80// CHECK-JAVA-INVOKE-NEXT:     check_five_struct_fp.skip(6);
81// CHECK-JAVA-INVOKE-NEXT:     invoke(mExportFuncIdx_check_five_struct, check_five_struct_fp);
82// CHECK-JAVA-INVOKE-NEXT: }
83
84// Some more structs with different field types and/or more fields.
85
86#pragma version(1)
87#pragma rs java_package_name(foo)
88
89typedef struct char_struct {
90    short f1;
91    // expect 6 bytes of padding here
92    long f2;
93} char_struct;
94
95char_struct g_char_struct;
96
97typedef struct five_struct {
98    char f1;
99    // expect 7 bytes of padding here
100    long f2;
101    short f3;
102    // expect 6 bytes of padding here
103    long f4;
104    half f5;
105    // expect 6 bytes of padding here
106} five_struct;
107
108five_struct g_five_struct;
109
110bool failed = false;
111
112void check_char_struct(short arg1, long arg2) {
113    failed |= ((g_char_struct.f1 != arg1) || (g_char_struct.f2 != arg2));
114}
115
116void check_five_struct(char arg1, long arg2, short arg3, long arg4, half arg5) {
117    failed |= ((g_five_struct.f1 != arg1) ||
118               (g_five_struct.f2 != arg2) ||
119               (g_five_struct.f3 != arg3) ||
120               (g_five_struct.f4 != arg4) ||
121               (g_five_struct.f5 != arg5));
122}
123