@@ -52,6 +52,9 @@ long long pass_longlong(long long arg) { return arg; }
52
52
__int128 pass_int128 (__int128 arg ) { return arg ; }
53
53
// CHECK-LABEL: define{{.*}} void @pass_int128(ptr dead_on_unwind noalias writable sret(i128) align 8 %{{.*}}, ptr %0)
54
54
55
+ _Float16 pass__Float16 (_Float16 arg ) { return arg ; }
56
+ // CHECK-LABEL: define{{.*}} half @pass__Float16(half %{{.*}})
57
+
55
58
float pass_float (float arg ) { return arg ; }
56
59
// CHECK-LABEL: define{{.*}} float @pass_float(float %{{.*}})
57
60
@@ -79,6 +82,9 @@ _Complex long pass_complex_long(_Complex long arg) { return arg; }
79
82
_Complex long long pass_complex_longlong (_Complex long long arg ) { return arg ; }
80
83
// CHECK-LABEL: define{{.*}} void @pass_complex_longlong(ptr dead_on_unwind noalias writable sret({ i64, i64 }) align 8 %{{.*}}, ptr %{{.*}}arg)
81
84
85
+ _Complex _Float16 pass_complex__Float16 (_Complex _Float16 arg ) { return arg ; }
86
+ // CHECK-LABEL: define{{.*}} void @pass_complex__Float16(ptr dead_on_unwind noalias writable sret({ half, half }) align 2 %{{.*}}, ptr %{{.*}}arg)
87
+
82
88
_Complex float pass_complex_float (_Complex float arg ) { return arg ; }
83
89
// CHECK-LABEL: define{{.*}} void @pass_complex_float(ptr dead_on_unwind noalias writable sret({ float, float }) align 4 %{{.*}}, ptr %{{.*}}arg)
84
90
@@ -130,6 +136,11 @@ struct agg_16byte pass_agg_16byte(struct agg_16byte arg) { return arg; }
130
136
131
137
// Float-like aggregate types
132
138
139
+ struct agg__Float16 { _Float16 a ; };
140
+ struct agg__Float16 pass_agg__Float16 (struct agg__Float16 arg ) { return arg ; }
141
+ // HARD-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16) align 2 %{{.*}}, half %{{.*}})
142
+ // SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16) align 2 %{{.*}}, i16 noext %{{.*}})
143
+
133
144
struct agg_float { float a ; };
134
145
struct agg_float pass_agg_float (struct agg_float arg ) { return arg ; }
135
146
// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float(ptr dead_on_unwind noalias writable sret(%struct.agg_float) align 4 %{{.*}}, float %{{.*}})
@@ -144,6 +155,20 @@ struct agg_longdouble { long double a; };
144
155
struct agg_longdouble pass_agg_longdouble (struct agg_longdouble arg ) { return arg ; }
145
156
// CHECK-LABEL: define{{.*}} void @pass_agg_longdouble(ptr dead_on_unwind noalias writable sret(%struct.agg_longdouble) align 8 %{{.*}}, ptr %{{.*}})
146
157
158
+ struct agg__Float16_a4 { _Float16 a __attribute__((aligned (4 ))); };
159
+ struct agg__Float16_a4 pass_agg__Float16_a4 (struct agg__Float16_a4 arg ) { return arg ; }
160
+ // HARD-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a4(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a4) align 4 %{{.*}}, float %{{.*}})
161
+ // SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a4(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a4) align 4 %{{.*}}, i32 noext %{{.*}})
162
+
163
+ struct agg__Float16_a8 { _Float16 a __attribute__((aligned (8 ))); };
164
+ struct agg__Float16_a8 pass_agg__Float16_a8 (struct agg__Float16_a8 arg ) { return arg ; }
165
+ // HARD-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a8(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a8) align 8 %{{.*}}, double %{{.*}})
166
+ // SOFT-FLOAT-LABEL: define{{.*}} void @pass_agg__Float16_a8(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a8) align 8 %{{.*}}, i64 %{{.*}})
167
+
168
+ struct agg__Float16_a16 { _Float16 a __attribute__((aligned (16 ))); };
169
+ struct agg__Float16_a16 pass_agg__Float16_a16 (struct agg__Float16_a16 arg ) { return arg ; }
170
+ // CHECK-LABEL: define{{.*}} void @pass_agg__Float16_a16(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16_a16) align 16 %{{.*}}, ptr %{{.*}})
171
+
147
172
struct agg_float_a8 { float a __attribute__((aligned (8 ))); };
148
173
struct agg_float_a8 pass_agg_float_a8 (struct agg_float_a8 arg ) { return arg ; }
149
174
// HARD-FLOAT-LABEL: define{{.*}} void @pass_agg_float_a8(ptr dead_on_unwind noalias writable sret(%struct.agg_float_a8) align 8 %{{.*}}, double %{{.*}})
@@ -171,6 +196,10 @@ struct agg_nofloat3 pass_agg_nofloat3(struct agg_nofloat3 arg) { return arg; }
171
196
172
197
// Union types likewise are *not* float-like aggregate types
173
198
199
+ union union__Float16 { _Float16 a ; };
200
+ union union__Float16 pass_union__Float16 (union union__Float16 arg ) { return arg ; }
201
+ // CHECK-LABEL: define{{.*}} void @pass_union__Float16(ptr dead_on_unwind noalias writable sret(%union.union__Float16) align 2 %{{.*}}, i16 noext %{{.*}})
202
+
174
203
union union_float { float a ; };
175
204
union union_float pass_union_float (union union_float arg ) { return arg ; }
176
205
// CHECK-LABEL: define{{.*}} void @pass_union_float(ptr dead_on_unwind noalias writable sret(%union.union_float) align 4 %{{.*}}, i32 noext %{{.*}})
@@ -448,6 +477,30 @@ struct agg_8byte va_agg_8byte(__builtin_va_list l) { return __builtin_va_arg(l,
448
477
// CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ]
449
478
// CHECK: ret void
450
479
480
+ struct agg__Float16 va_agg__Float16 (__builtin_va_list l ) { return __builtin_va_arg (l , struct agg__Float16 ); }
481
+ // CHECK-LABEL: define{{.*}} void @va_agg__Float16(ptr dead_on_unwind noalias writable sret(%struct.agg__Float16) align 2 %{{.*}}, ptr %{{.*}}
482
+ // HARD-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 1
483
+ // SOFT-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 0
484
+ // CHECK: [[REG_COUNT:%[^ ]+]] = load i64, ptr [[REG_COUNT_PTR]]
485
+ // HARD-FLOAT: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 4
486
+ // SOFT-FLOAT: [[FITS_IN_REGS:%[^ ]+]] = icmp ult i64 [[REG_COUNT]], 5
487
+ // CHECK: br i1 [[FITS_IN_REGS]],
488
+ // CHECK: [[SCALED_REG_COUNT:%[^ ]+]] = mul i64 [[REG_COUNT]], 8
489
+ // HARD-FLOAT: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 128
490
+ // SOFT-FLOAT: [[REG_OFFSET:%[^ ]+]] = add i64 [[SCALED_REG_COUNT]], 22
491
+ // CHECK: [[REG_SAVE_AREA_PTR:%[^ ]+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 3
492
+ // CHECK: [[REG_SAVE_AREA:%[^ ]+]] = load ptr, ptr [[REG_SAVE_AREA_PTR:[^ ]+]]
493
+ // CHECK: [[RAW_REG_ADDR:%[^ ]+]] = getelementptr i8, ptr [[REG_SAVE_AREA]], i64 [[REG_OFFSET]]
494
+ // CHECK: [[REG_COUNT1:%[^ ]+]] = add i64 [[REG_COUNT]], 1
495
+ // CHECK: store i64 [[REG_COUNT1]], ptr [[REG_COUNT_PTR]]
496
+ // CHECK: [[OVERFLOW_ARG_AREA_PTR:%[^ ]+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 2
497
+ // CHECK: [[OVERFLOW_ARG_AREA:%[^ ]+]] = load ptr, ptr [[OVERFLOW_ARG_AREA_PTR]]
498
+ // CHECK: [[RAW_MEM_ADDR:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 6
499
+ // CHECK: [[OVERFLOW_ARG_AREA2:%[^ ]+]] = getelementptr i8, ptr [[OVERFLOW_ARG_AREA]], i64 8
500
+ // CHECK: store ptr [[OVERFLOW_ARG_AREA2]], ptr [[OVERFLOW_ARG_AREA_PTR]]
501
+ // CHECK: [[VA_ARG_ADDR:%[^ ]+]] = phi ptr [ [[RAW_REG_ADDR]], %{{.*}} ], [ [[RAW_MEM_ADDR]], %{{.*}} ]
502
+ // CHECK: ret void
503
+
451
504
struct agg_float va_agg_float (__builtin_va_list l ) { return __builtin_va_arg (l , struct agg_float ); }
452
505
// CHECK-LABEL: define{{.*}} void @va_agg_float(ptr dead_on_unwind noalias writable sret(%struct.agg_float) align 4 %{{.*}}, ptr %{{.*}}
453
506
// HARD-FLOAT: [[REG_COUNT_PTR:%[^ ]+]] = getelementptr inbounds nuw %struct.__va_list_tag, ptr %{{.*}}, i32 0, i32 1
0 commit comments