Home | History | Annotate | Download | only in CodeGen
      1 // RUN: %clang_cc1 -faltivec -triple powerpc64le-unknown-linux-gnu -emit-llvm -o - %s | FileCheck %s
      2 
      3 // Test homogeneous float aggregate passing and returning.
      4 
      5 struct f1 { float f[1]; };
      6 struct f2 { float f[2]; };
      7 struct f3 { float f[3]; };
      8 struct f4 { float f[4]; };
      9 struct f5 { float f[5]; };
     10 struct f6 { float f[6]; };
     11 struct f7 { float f[7]; };
     12 struct f8 { float f[8]; };
     13 struct f9 { float f[9]; };
     14 
     15 struct fab { float a; float b; };
     16 struct fabc { float a; float b; float c; };
     17 
     18 struct f2a2b { float a[2]; float b[2]; };
     19 
     20 // CHECK: define [1 x float] @func_f1(float inreg %x.coerce)
     21 struct f1 func_f1(struct f1 x) { return x; }
     22 
     23 // CHECK: define [2 x float] @func_f2([2 x float] %x.coerce)
     24 struct f2 func_f2(struct f2 x) { return x; }
     25 
     26 // CHECK: define [3 x float] @func_f3([3 x float] %x.coerce)
     27 struct f3 func_f3(struct f3 x) { return x; }
     28 
     29 // CHECK: define [4 x float] @func_f4([4 x float] %x.coerce)
     30 struct f4 func_f4(struct f4 x) { return x; }
     31 
     32 // CHECK: define [5 x float] @func_f5([5 x float] %x.coerce)
     33 struct f5 func_f5(struct f5 x) { return x; }
     34 
     35 // CHECK: define [6 x float] @func_f6([6 x float] %x.coerce)
     36 struct f6 func_f6(struct f6 x) { return x; }
     37 
     38 // CHECK: define [7 x float] @func_f7([7 x float] %x.coerce)
     39 struct f7 func_f7(struct f7 x) { return x; }
     40 
     41 // CHECK: define [8 x float] @func_f8([8 x float] %x.coerce)
     42 struct f8 func_f8(struct f8 x) { return x; }
     43 
     44 // CHECK: define void @func_f9(%struct.f9* noalias sret %agg.result, [5 x i64] %x.coerce)
     45 struct f9 func_f9(struct f9 x) { return x; }
     46 
     47 // CHECK: define [2 x float] @func_fab([2 x float] %x.coerce)
     48 struct fab func_fab(struct fab x) { return x; }
     49 
     50 // CHECK: define [3 x float] @func_fabc([3 x float] %x.coerce)
     51 struct fabc func_fabc(struct fabc x) { return x; }
     52 
     53 // CHECK: define [4 x float] @func_f2a2b([4 x float] %x.coerce)
     54 struct f2a2b func_f2a2b(struct f2a2b x) { return x; }
     55 
     56 // CHECK-LABEL: @call_f1
     57 // CHECK: %[[TMP:[^ ]+]] = load float, float* getelementptr inbounds (%struct.f1, %struct.f1* @global_f1, i32 0, i32 0, i32 0), align 4
     58 // CHECK: call [1 x float] @func_f1(float inreg %[[TMP]])
     59 struct f1 global_f1;
     60 void call_f1(void) { global_f1 = func_f1(global_f1); }
     61 
     62 // CHECK-LABEL: @call_f2
     63 // CHECK: %[[TMP:[^ ]+]] = load [2 x float], [2 x float]* getelementptr inbounds (%struct.f2, %struct.f2* @global_f2, i32 0, i32 0), align 4
     64 // CHECK: call [2 x float] @func_f2([2 x float] %[[TMP]])
     65 struct f2 global_f2;
     66 void call_f2(void) { global_f2 = func_f2(global_f2); }
     67 
     68 // CHECK-LABEL: @call_f3
     69 // CHECK: %[[TMP:[^ ]+]] = load [3 x float], [3 x float]* getelementptr inbounds (%struct.f3, %struct.f3* @global_f3, i32 0, i32 0), align 4
     70 // CHECK: call [3 x float] @func_f3([3 x float] %[[TMP]])
     71 struct f3 global_f3;
     72 void call_f3(void) { global_f3 = func_f3(global_f3); }
     73 
     74 // CHECK-LABEL: @call_f4
     75 // CHECK: %[[TMP:[^ ]+]] = load [4 x float], [4 x float]* getelementptr inbounds (%struct.f4, %struct.f4* @global_f4, i32 0, i32 0), align 4
     76 // CHECK: call [4 x float] @func_f4([4 x float] %[[TMP]])
     77 struct f4 global_f4;
     78 void call_f4(void) { global_f4 = func_f4(global_f4); }
     79 
     80 // CHECK-LABEL: @call_f5
     81 // CHECK: %[[TMP:[^ ]+]] = load [5 x float], [5 x float]* getelementptr inbounds (%struct.f5, %struct.f5* @global_f5, i32 0, i32 0), align 4
     82 // CHECK: call [5 x float] @func_f5([5 x float] %[[TMP]])
     83 struct f5 global_f5;
     84 void call_f5(void) { global_f5 = func_f5(global_f5); }
     85 
     86 // CHECK-LABEL: @call_f6
     87 // CHECK: %[[TMP:[^ ]+]] = load [6 x float], [6 x float]* getelementptr inbounds (%struct.f6, %struct.f6* @global_f6, i32 0, i32 0), align 4
     88 // CHECK: call [6 x float] @func_f6([6 x float] %[[TMP]])
     89 struct f6 global_f6;
     90 void call_f6(void) { global_f6 = func_f6(global_f6); }
     91 
     92 // CHECK-LABEL: @call_f7
     93 // CHECK: %[[TMP:[^ ]+]] = load [7 x float], [7 x float]* getelementptr inbounds (%struct.f7, %struct.f7* @global_f7, i32 0, i32 0), align 4
     94 // CHECK: call [7 x float] @func_f7([7 x float] %[[TMP]])
     95 struct f7 global_f7;
     96 void call_f7(void) { global_f7 = func_f7(global_f7); }
     97 
     98 // CHECK-LABEL: @call_f8
     99 // CHECK: %[[TMP:[^ ]+]] = load [8 x float], [8 x float]* getelementptr inbounds (%struct.f8, %struct.f8* @global_f8, i32 0, i32 0), align 4
    100 // CHECK: call [8 x float] @func_f8([8 x float] %[[TMP]])
    101 struct f8 global_f8;
    102 void call_f8(void) { global_f8 = func_f8(global_f8); }
    103 
    104 // CHECK-LABEL: @call_f9
    105 // CHECK: %[[TMP1:[^ ]+]] = alloca [5 x i64]
    106 // CHECK: %[[TMP2:[^ ]+]] = bitcast [5 x i64]* %[[TMP1]] to i8*
    107 // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %[[TMP2]], i8* bitcast (%struct.f9* @global_f9 to i8*), i64 36, i32 4, i1 false)
    108 // CHECK: %[[TMP3:[^ ]+]] = load [5 x i64], [5 x i64]* %[[TMP1]]
    109 // CHECK: call void @func_f9(%struct.f9* sret %{{[^ ]+}}, [5 x i64] %[[TMP3]])
    110 struct f9 global_f9;
    111 void call_f9(void) { global_f9 = func_f9(global_f9); }
    112 
    113 // CHECK-LABEL: @call_fab
    114 // CHECK: %[[TMP:[^ ]+]] = load [2 x float], [2 x float]* bitcast (%struct.fab* @global_fab to [2 x float]*)
    115 // CHECK: call [2 x float] @func_fab([2 x float] %[[TMP]])
    116 struct fab global_fab;
    117 void call_fab(void) { global_fab = func_fab(global_fab); }
    118 
    119 // CHECK-LABEL: @call_fabc
    120 // CHECK: %[[TMP:[^ ]+]] = load [3 x float], [3 x float]* bitcast (%struct.fabc* @global_fabc to [3 x float]*)
    121 // CHECK: call [3 x float] @func_fabc([3 x float] %[[TMP]])
    122 struct fabc global_fabc;
    123 void call_fabc(void) { global_fabc = func_fabc(global_fabc); }
    124 
    125 
    126 // Test homogeneous vector aggregate passing and returning.
    127 
    128 struct v1 { vector int v[1]; };
    129 struct v2 { vector int v[2]; };
    130 struct v3 { vector int v[3]; };
    131 struct v4 { vector int v[4]; };
    132 struct v5 { vector int v[5]; };
    133 struct v6 { vector int v[6]; };
    134 struct v7 { vector int v[7]; };
    135 struct v8 { vector int v[8]; };
    136 struct v9 { vector int v[9]; };
    137 
    138 struct vab { vector int a; vector int b; };
    139 struct vabc { vector int a; vector int b; vector int c; };
    140 
    141 // CHECK: define [1 x <4 x i32>] @func_v1(<4 x i32> inreg %x.coerce)
    142 struct v1 func_v1(struct v1 x) { return x; }
    143 
    144 // CHECK: define [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %x.coerce)
    145 struct v2 func_v2(struct v2 x) { return x; }
    146 
    147 // CHECK: define [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %x.coerce)
    148 struct v3 func_v3(struct v3 x) { return x; }
    149 
    150 // CHECK: define [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %x.coerce)
    151 struct v4 func_v4(struct v4 x) { return x; }
    152 
    153 // CHECK: define [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %x.coerce)
    154 struct v5 func_v5(struct v5 x) { return x; }
    155 
    156 // CHECK: define [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %x.coerce)
    157 struct v6 func_v6(struct v6 x) { return x; }
    158 
    159 // CHECK: define [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %x.coerce)
    160 struct v7 func_v7(struct v7 x) { return x; }
    161 
    162 // CHECK: define [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %x.coerce)
    163 struct v8 func_v8(struct v8 x) { return x; }
    164 
    165 // CHECK: define void @func_v9(%struct.v9* noalias sret %agg.result, %struct.v9* byval align 16 %x)
    166 struct v9 func_v9(struct v9 x) { return x; }
    167 
    168 // CHECK: define [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %x.coerce)
    169 struct vab func_vab(struct vab x) { return x; }
    170 
    171 // CHECK: define [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %x.coerce)
    172 struct vabc func_vabc(struct vabc x) { return x; }
    173 
    174 // CHECK-LABEL: @call_v1
    175 // CHECK: %[[TMP:[^ ]+]] = load <4 x i32>, <4 x i32>* getelementptr inbounds (%struct.v1, %struct.v1* @global_v1, i32 0, i32 0, i32 0), align 1
    176 // CHECK: call [1 x <4 x i32>] @func_v1(<4 x i32> inreg %[[TMP]])
    177 struct v1 global_v1;
    178 void call_v1(void) { global_v1 = func_v1(global_v1); }
    179 
    180 // CHECK-LABEL: @call_v2
    181 // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>], [2 x <4 x i32>]* getelementptr inbounds (%struct.v2, %struct.v2* @global_v2, i32 0, i32 0), align 1
    182 // CHECK: call [2 x <4 x i32>] @func_v2([2 x <4 x i32>] %[[TMP]])
    183 struct v2 global_v2;
    184 void call_v2(void) { global_v2 = func_v2(global_v2); }
    185 
    186 // CHECK-LABEL: @call_v3
    187 // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>], [3 x <4 x i32>]* getelementptr inbounds (%struct.v3, %struct.v3* @global_v3, i32 0, i32 0), align 1
    188 // CHECK: call [3 x <4 x i32>] @func_v3([3 x <4 x i32>] %[[TMP]])
    189 struct v3 global_v3;
    190 void call_v3(void) { global_v3 = func_v3(global_v3); }
    191 
    192 // CHECK-LABEL: @call_v4
    193 // CHECK: %[[TMP:[^ ]+]] = load [4 x <4 x i32>], [4 x <4 x i32>]* getelementptr inbounds (%struct.v4, %struct.v4* @global_v4, i32 0, i32 0), align 1
    194 // CHECK: call [4 x <4 x i32>] @func_v4([4 x <4 x i32>] %[[TMP]])
    195 struct v4 global_v4;
    196 void call_v4(void) { global_v4 = func_v4(global_v4); }
    197 
    198 // CHECK-LABEL: @call_v5
    199 // CHECK: %[[TMP:[^ ]+]] = load [5 x <4 x i32>], [5 x <4 x i32>]* getelementptr inbounds (%struct.v5, %struct.v5* @global_v5, i32 0, i32 0), align 1
    200 // CHECK: call [5 x <4 x i32>] @func_v5([5 x <4 x i32>] %[[TMP]])
    201 struct v5 global_v5;
    202 void call_v5(void) { global_v5 = func_v5(global_v5); }
    203 
    204 // CHECK-LABEL: @call_v6
    205 // CHECK: %[[TMP:[^ ]+]] = load [6 x <4 x i32>], [6 x <4 x i32>]* getelementptr inbounds (%struct.v6, %struct.v6* @global_v6, i32 0, i32 0), align 1
    206 // CHECK: call [6 x <4 x i32>] @func_v6([6 x <4 x i32>] %[[TMP]])
    207 struct v6 global_v6;
    208 void call_v6(void) { global_v6 = func_v6(global_v6); }
    209 
    210 // CHECK-LABEL: @call_v7
    211 // CHECK: %[[TMP:[^ ]+]] = load [7 x <4 x i32>], [7 x <4 x i32>]* getelementptr inbounds (%struct.v7, %struct.v7* @global_v7, i32 0, i32 0), align 1
    212 // CHECK: call [7 x <4 x i32>] @func_v7([7 x <4 x i32>] %[[TMP]])
    213 struct v7 global_v7;
    214 void call_v7(void) { global_v7 = func_v7(global_v7); }
    215 
    216 // CHECK-LABEL: @call_v8
    217 // CHECK: %[[TMP:[^ ]+]] = load [8 x <4 x i32>], [8 x <4 x i32>]* getelementptr inbounds (%struct.v8, %struct.v8* @global_v8, i32 0, i32 0), align 1
    218 // CHECK: call [8 x <4 x i32>] @func_v8([8 x <4 x i32>] %[[TMP]])
    219 struct v8 global_v8;
    220 void call_v8(void) { global_v8 = func_v8(global_v8); }
    221 
    222 // CHECK-LABEL: @call_v9
    223 // CHECK: call void @func_v9(%struct.v9* sret %{{[^ ]+}}, %struct.v9* byval align 16 @global_v9)
    224 struct v9 global_v9;
    225 void call_v9(void) { global_v9 = func_v9(global_v9); }
    226 
    227 // CHECK-LABEL: @call_vab
    228 // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x i32>], [2 x <4 x i32>]* bitcast (%struct.vab* @global_vab to [2 x <4 x i32>]*)
    229 // CHECK: call [2 x <4 x i32>] @func_vab([2 x <4 x i32>] %[[TMP]])
    230 struct vab global_vab;
    231 void call_vab(void) { global_vab = func_vab(global_vab); }
    232 
    233 // CHECK-LABEL: @call_vabc
    234 // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x i32>], [3 x <4 x i32>]* bitcast (%struct.vabc* @global_vabc to [3 x <4 x i32>]*)
    235 // CHECK: call [3 x <4 x i32>] @func_vabc([3 x <4 x i32>] %[[TMP]])
    236 struct vabc global_vabc;
    237 void call_vabc(void) { global_vabc = func_vabc(global_vabc); }
    238 
    239 
    240 // As clang extension, non-power-of-two vectors may also be part of
    241 // homogeneous aggregates.
    242 
    243 typedef float float3 __attribute__((vector_size (12)));
    244 
    245 struct v3f1 { float3 v[1]; };
    246 struct v3f2 { float3 v[2]; };
    247 struct v3f3 { float3 v[3]; };
    248 struct v3f4 { float3 v[4]; };
    249 struct v3f5 { float3 v[5]; };
    250 struct v3f6 { float3 v[6]; };
    251 struct v3f7 { float3 v[7]; };
    252 struct v3f8 { float3 v[8]; };
    253 struct v3f9 { float3 v[9]; };
    254 
    255 struct v3fab { float3 a; float3 b; };
    256 struct v3fabc { float3 a; float3 b; float3 c; };
    257 
    258 // CHECK: define [1 x <4 x float>] @func_v3f1(<3 x float> inreg %x.coerce)
    259 struct v3f1 func_v3f1(struct v3f1 x) { return x; }
    260 
    261 // CHECK: define [2 x <4 x float>] @func_v3f2([2 x <4 x float>] %x.coerce)
    262 struct v3f2 func_v3f2(struct v3f2 x) { return x; }
    263 
    264 // CHECK: define [3 x <4 x float>] @func_v3f3([3 x <4 x float>] %x.coerce)
    265 struct v3f3 func_v3f3(struct v3f3 x) { return x; }
    266 
    267 // CHECK: define [4 x <4 x float>] @func_v3f4([4 x <4 x float>] %x.coerce)
    268 struct v3f4 func_v3f4(struct v3f4 x) { return x; }
    269 
    270 // CHECK: define [5 x <4 x float>] @func_v3f5([5 x <4 x float>] %x.coerce)
    271 struct v3f5 func_v3f5(struct v3f5 x) { return x; }
    272 
    273 // CHECK: define [6 x <4 x float>] @func_v3f6([6 x <4 x float>] %x.coerce)
    274 struct v3f6 func_v3f6(struct v3f6 x) { return x; }
    275 
    276 // CHECK: define [7 x <4 x float>] @func_v3f7([7 x <4 x float>] %x.coerce)
    277 struct v3f7 func_v3f7(struct v3f7 x) { return x; }
    278 
    279 // CHECK: define [8 x <4 x float>] @func_v3f8([8 x <4 x float>] %x.coerce)
    280 struct v3f8 func_v3f8(struct v3f8 x) { return x; }
    281 
    282 // CHECK: define void @func_v3f9(%struct.v3f9* noalias sret %agg.result, %struct.v3f9* byval align 16 %x)
    283 struct v3f9 func_v3f9(struct v3f9 x) { return x; }
    284 
    285 // CHECK: define [2 x <4 x float>] @func_v3fab([2 x <4 x float>] %x.coerce)
    286 struct v3fab func_v3fab(struct v3fab x) { return x; }
    287 
    288 // CHECK: define [3 x <4 x float>] @func_v3fabc([3 x <4 x float>] %x.coerce)
    289 struct v3fabc func_v3fabc(struct v3fabc x) { return x; }
    290 
    291 // CHECK-LABEL: @call_v3f1
    292 // CHECK: %[[TMP:[^ ]+]] = load <3 x float>, <3 x float>* getelementptr inbounds (%struct.v3f1, %struct.v3f1* @global_v3f1, i32 0, i32 0, i32 0), align 1
    293 // CHECK: call [1 x <4 x float>] @func_v3f1(<3 x float> inreg %[[TMP]])
    294 struct v3f1 global_v3f1;
    295 void call_v3f1(void) { global_v3f1 = func_v3f1(global_v3f1); }
    296 
    297 // CHECK-LABEL: @call_v3f2
    298 // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x float>], [2 x <4 x float>]* bitcast (%struct.v3f2* @global_v3f2 to [2 x <4 x float>]*), align 16
    299 // CHECK: call [2 x <4 x float>] @func_v3f2([2 x <4 x float>] %[[TMP]])
    300 struct v3f2 global_v3f2;
    301 void call_v3f2(void) { global_v3f2 = func_v3f2(global_v3f2); }
    302 
    303 // CHECK-LABEL: @call_v3f3
    304 // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x float>], [3 x <4 x float>]* bitcast (%struct.v3f3* @global_v3f3 to [3 x <4 x float>]*), align 16
    305 // CHECK: call [3 x <4 x float>] @func_v3f3([3 x <4 x float>] %[[TMP]])
    306 struct v3f3 global_v3f3;
    307 void call_v3f3(void) { global_v3f3 = func_v3f3(global_v3f3); }
    308 
    309 // CHECK-LABEL: @call_v3f4
    310 // CHECK: %[[TMP:[^ ]+]] = load [4 x <4 x float>], [4 x <4 x float>]* bitcast (%struct.v3f4* @global_v3f4 to [4 x <4 x float>]*), align 16
    311 // CHECK: call [4 x <4 x float>] @func_v3f4([4 x <4 x float>] %[[TMP]])
    312 struct v3f4 global_v3f4;
    313 void call_v3f4(void) { global_v3f4 = func_v3f4(global_v3f4); }
    314 
    315 // CHECK-LABEL: @call_v3f5
    316 // CHECK: %[[TMP:[^ ]+]] = load [5 x <4 x float>], [5 x <4 x float>]* bitcast (%struct.v3f5* @global_v3f5 to [5 x <4 x float>]*), align 16
    317 // CHECK: call [5 x <4 x float>] @func_v3f5([5 x <4 x float>] %[[TMP]])
    318 struct v3f5 global_v3f5;
    319 void call_v3f5(void) { global_v3f5 = func_v3f5(global_v3f5); }
    320 
    321 // CHECK-LABEL: @call_v3f6
    322 // CHECK: %[[TMP:[^ ]+]] = load [6 x <4 x float>], [6 x <4 x float>]* bitcast (%struct.v3f6* @global_v3f6 to [6 x <4 x float>]*), align 16
    323 // CHECK: call [6 x <4 x float>] @func_v3f6([6 x <4 x float>] %[[TMP]])
    324 struct v3f6 global_v3f6;
    325 void call_v3f6(void) { global_v3f6 = func_v3f6(global_v3f6); }
    326 
    327 // CHECK-LABEL: @call_v3f7
    328 // CHECK: %[[TMP:[^ ]+]] = load [7 x <4 x float>], [7 x <4 x float>]* bitcast (%struct.v3f7* @global_v3f7 to [7 x <4 x float>]*), align 16
    329 // CHECK: call [7 x <4 x float>] @func_v3f7([7 x <4 x float>] %[[TMP]])
    330 struct v3f7 global_v3f7;
    331 void call_v3f7(void) { global_v3f7 = func_v3f7(global_v3f7); }
    332 
    333 // CHECK-LABEL: @call_v3f8
    334 // CHECK: %[[TMP:[^ ]+]] = load [8 x <4 x float>], [8 x <4 x float>]* bitcast (%struct.v3f8* @global_v3f8 to [8 x <4 x float>]*), align 16
    335 // CHECK: call [8 x <4 x float>] @func_v3f8([8 x <4 x float>] %[[TMP]])
    336 struct v3f8 global_v3f8;
    337 void call_v3f8(void) { global_v3f8 = func_v3f8(global_v3f8); }
    338 
    339 // CHECK-LABEL: @call_v3f9
    340 // CHECK: call void @func_v3f9(%struct.v3f9* sret %{{[^ ]+}}, %struct.v3f9* byval align 16 @global_v3f9)
    341 struct v3f9 global_v3f9;
    342 void call_v3f9(void) { global_v3f9 = func_v3f9(global_v3f9); }
    343 
    344 // CHECK-LABEL: @call_v3fab
    345 // CHECK: %[[TMP:[^ ]+]] = load [2 x <4 x float>], [2 x <4 x float>]* bitcast (%struct.v3fab* @global_v3fab to [2 x <4 x float>]*), align 16
    346 // CHECK: call [2 x <4 x float>] @func_v3fab([2 x <4 x float>] %[[TMP]])
    347 struct v3fab global_v3fab;
    348 void call_v3fab(void) { global_v3fab = func_v3fab(global_v3fab); }
    349 
    350 // CHECK-LABEL: @call_v3fabc
    351 // CHECK: %[[TMP:[^ ]+]] = load [3 x <4 x float>], [3 x <4 x float>]* bitcast (%struct.v3fabc* @global_v3fabc to [3 x <4 x float>]*), align 16
    352 // CHECK: call [3 x <4 x float>] @func_v3fabc([3 x <4 x float>] %[[TMP]])
    353 struct v3fabc global_v3fabc;
    354 void call_v3fabc(void) { global_v3fabc = func_v3fabc(global_v3fabc); }
    355 
    356 
    357 // Test returning small aggregates.
    358 
    359 struct s1 { char c[1]; };
    360 struct s2 { char c[2]; };
    361 struct s3 { char c[3]; };
    362 struct s4 { char c[4]; };
    363 struct s5 { char c[5]; };
    364 struct s6 { char c[6]; };
    365 struct s7 { char c[7]; };
    366 struct s8 { char c[8]; };
    367 struct s9 { char c[9]; };
    368 struct s16 { char c[16]; };
    369 struct s17 { char c[17]; };
    370 
    371 // CHECK: define i8 @ret_s1()
    372 struct s1 ret_s1() {
    373   return (struct s1) { 17 };
    374 }
    375 
    376 // CHECK: define i16 @ret_s2()
    377 struct s2 ret_s2() {
    378   return (struct s2) { 17, 18 };
    379 }
    380 
    381 // CHECK: define i24 @ret_s3()
    382 struct s3 ret_s3() {
    383   return (struct s3) { 17, 18, 19 };
    384 }
    385 
    386 // CHECK: define i32 @ret_s4()
    387 struct s4 ret_s4() {
    388   return (struct s4) { 17, 18, 19, 20 };
    389 }
    390 
    391 // CHECK: define i40 @ret_s5()
    392 struct s5 ret_s5() {
    393   return (struct s5) { 17, 18, 19, 20, 21 };
    394 }
    395 
    396 // CHECK: define i48 @ret_s6()
    397 struct s6 ret_s6() {
    398   return (struct s6) { 17, 18, 19, 20, 21, 22 };
    399 }
    400 
    401 // CHECK: define i56 @ret_s7()
    402 struct s7 ret_s7() {
    403   return (struct s7) { 17, 18, 19, 20, 21, 22, 23 };
    404 }
    405 
    406 // CHECK: define i64 @ret_s8()
    407 struct s8 ret_s8() {
    408   return (struct s8) { 17, 18, 19, 20, 21, 22, 23, 24 };
    409 }
    410 
    411 // CHECK: define { i64, i64 } @ret_s9()
    412 struct s9 ret_s9() {
    413   return (struct s9) { 17, 18, 19, 20, 21, 22, 23, 24, 25 };
    414 }
    415 
    416 // CHECK: define { i64, i64 } @ret_s16()
    417 struct s16 ret_s16() {
    418   return (struct s16) { 17, 18, 19, 20, 21, 22, 23, 24,
    419                         25, 26, 27, 28, 29, 30, 31, 32 };
    420 }
    421 
    422 // CHECK: define void @ret_s17(%struct.s17*
    423 struct s17 ret_s17() {
    424   return (struct s17) { 17, 18, 19, 20, 21, 22, 23, 24,
    425                         25, 26, 27, 28, 29, 30, 31, 32, 33 };
    426 }
    427 
    428