@@ -53,16 +53,16 @@ pub struct ForceAlign4 {
5353 b : i8 ,
5454}
5555
56- // on i686-windows, this should be passed on stack using `byval`
56+ // On i686-windows, this is passed on stack using `byval`
5757#[ repr( C ) ]
5858pub struct NaturalAlign8 {
5959 a : i64 ,
6060 b : i64 ,
6161 c : i64
6262}
6363
64- // on i686-windows, this is passed by reference (because alignment is >4 and requested/forced),
65- // even though it has the exact same layout as `NaturalAlign8` (!!!)
64+ // On i686-windows, this is passed by reference (because alignment is >4 and requested/forced),
65+ // even though it has the exact same layout as `NaturalAlign8`!
6666#[ repr( C ) ]
6767#[ repr( align( 8 ) ) ]
6868pub struct ForceAlign8 {
@@ -71,6 +71,30 @@ pub struct ForceAlign8 {
7171 c : i64
7272}
7373
74+ // On i686-windows, this is passed by reference because alignment is requested,
75+ // even though the requested alignment is less than the natural alignment.
76+ #[ repr( C ) ]
77+ #[ repr( align( 1 ) ) ]
78+ pub struct LowerFA8 {
79+ a : i64 ,
80+ b : i64 ,
81+ c : i64
82+ }
83+
84+ // On i686-windows, this is passed on stack again, because the wrapper struct does not have
85+ // requested/forced alignment.
86+ #[ repr( C ) ]
87+ pub struct WrappedFA8 {
88+ a : ForceAlign8
89+ }
90+
91+ // On i686-windows, this has the same ABI as ForceAlign8, i.e. passed by reference.
92+ #[ repr( transparent) ]
93+ pub struct TransparentFA8 {
94+ _0 : ( ) ,
95+ a : ForceAlign8
96+ }
97+
7498#[ repr( C ) ]
7599#[ repr( align( 16 ) ) ]
76100pub struct ForceAlign16 {
@@ -143,6 +167,30 @@ pub unsafe fn call_fa8(x: ForceAlign8) {
143167 force_align_8 ( x) ;
144168}
145169
170+ // CHECK-LABEL: @call_lfa8
171+ #[ no_mangle]
172+ pub unsafe fn call_lfa8 ( x : LowerFA8 ) {
173+ // CHECK: start:
174+ // CHECK-NEXT: call void @lower_fa8
175+ lower_fa8 ( x) ;
176+ }
177+
178+ // CHECK-LABEL: @call_wfa8
179+ #[ no_mangle]
180+ pub unsafe fn call_wfa8 ( x : WrappedFA8 ) {
181+ // CHECK: start:
182+ // CHECK-NEXT: call void @wrapped_fa8
183+ wrapped_fa8 ( x) ;
184+ }
185+
186+ // CHECK-LABEL: @call_tfa8
187+ #[ no_mangle]
188+ pub unsafe fn call_tfa8 ( x : TransparentFA8 ) {
189+ // CHECK: start:
190+ // CHECK-NEXT: call void @transparent_fa8
191+ transparent_fa8 ( x) ;
192+ }
193+
146194// CHECK-LABEL: @call_fa16
147195#[ no_mangle]
148196pub unsafe fn call_fa16 ( x : ForceAlign16 ) {
@@ -227,6 +275,55 @@ extern "C" {
227275 // i686-windows-SAME: align 8{{.*}})
228276 fn force_align_8 ( x : ForceAlign8 ) ;
229277
278+ // m68k: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}})
279+
280+ // wasm: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}})
281+
282+ // x86_64-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 8{{.*}})
283+
284+ // x86_64-windows: declare void @lower_fa8(
285+ // x86_64-windows-NOT: byval
286+ // x86_64-windows-SAME: align 8{{.*}})
287+
288+ // i686-linux: declare void @lower_fa8({{.*}}byval(%LowerFA8) align 4{{.*}})
289+
290+ // i686-windows: declare void @lower_fa8(
291+ // i686-windows-NOT: byval
292+ // i686-windows-SAME: align 8{{.*}})
293+ fn lower_fa8 ( x : LowerFA8 ) ;
294+
295+ // m68k: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}})
296+
297+ // wasm: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}})
298+
299+ // x86_64-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 8{{.*}})
300+
301+ // x86_64-windows: declare void @wrapped_fa8(
302+ // x86_64-windows-NOT: byval
303+ // x86_64-windows-SAME: align 8{{.*}})
304+
305+ // i686-linux: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 4{{.*}})
306+
307+ // i686-windows: declare void @wrapped_fa8({{.*}}byval(%WrappedFA8) align 4{{.*}})
308+ fn wrapped_fa8 ( x : WrappedFA8 ) ;
309+
310+ // m68k: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}})
311+
312+ // wasm: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}})
313+
314+ // x86_64-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 8{{.*}})
315+
316+ // x86_64-windows: declare void @transparent_fa8(
317+ // x86_64-windows-NOT: byval
318+ // x86_64-windows-SAME: align 8{{.*}})
319+
320+ // i686-linux: declare void @transparent_fa8({{.*}}byval(%TransparentFA8) align 4{{.*}})
321+
322+ // i686-windows: declare void @transparent_fa8(
323+ // i686-windows-NOT: byval
324+ // i686-windows-SAME: align 8{{.*}})
325+ fn transparent_fa8 ( x : TransparentFA8 ) ;
326+
230327 // m68k: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}})
231328
232329 // wasm: declare void @force_align_16({{.*}}byval(%ForceAlign16) align 16{{.*}})
0 commit comments