1 // Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 // compile-flags: -C no-prepopulate-passes
14 #![feature(repr_simd)]
16 use std
::marker
::PhantomData
;
24 // CHECK: define float @test_F32(float %arg0)
26 pub extern fn test_F32(_
: F32
) -> F32 { loop {}
}
29 pub struct Ptr(*mut u8);
31 // CHECK: define i8* @test_Ptr(i8* %arg0)
33 pub extern fn test_Ptr(_
: Ptr
) -> Ptr { loop {}
}
36 pub struct WithZst(u64, Zst1
);
38 // CHECK: define i64 @test_WithZst(i64 %arg0)
40 pub extern fn test_WithZst(_
: WithZst
) -> WithZst { loop {}
}
43 pub struct WithZeroSizedArray(*const f32, [i8; 0]);
45 // Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
46 // CHECK: define i32* @test_WithZeroSizedArray(i32* %arg0)
48 pub extern fn test_WithZeroSizedArray(_
: WithZeroSizedArray
) -> WithZeroSizedArray { loop {}
}
51 pub struct Generic
<T
>(T
);
53 // CHECK: define double @test_Generic(double %arg0)
55 pub extern fn test_Generic(_
: Generic
<f64>) -> Generic
<f64> { loop {}
}
58 pub struct GenericPlusZst
<T
>(T
, Zst2
);
61 pub enum Bool { True, False, FileNotFound }
63 // CHECK: define{{( zeroext)?}} i8 @test_Gpz(i8{{( zeroext)?}} %arg0)
65 pub extern fn test_Gpz(_
: GenericPlusZst
<Bool
>) -> GenericPlusZst
<Bool
> { loop {}
}
68 pub struct LifetimePhantom
<'a
, T
: 'a
>(*const T
, PhantomData
<&'a T
>);
70 // CHECK: define i16* @test_LifetimePhantom(i16* %arg0)
72 pub extern fn test_LifetimePhantom(_
: LifetimePhantom
<i16>) -> LifetimePhantom
<i16> { loop {}
}
74 // This works despite current alignment resrictions because PhantomData is always align(1)
76 pub struct UnitPhantom
<T
, U
> { val: T, unit: PhantomData<U> }
80 // CHECK: define float @test_UnitPhantom(float %arg0)
82 pub extern fn test_UnitPhantom(_
: UnitPhantom
<f32, Px
>) -> UnitPhantom
<f32, Px
> { loop {}
}
85 pub struct TwoZsts(Zst1
, i8, Zst2
);
87 // CHECK: define{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %arg0)
89 pub extern fn test_TwoZsts(_
: TwoZsts
) -> TwoZsts { loop {}
}
92 pub struct Nested1(Zst2
, Generic
<f64>);
94 // CHECK: define double @test_Nested1(double %arg0)
96 pub extern fn test_Nested1(_
: Nested1
) -> Nested1 { loop {}
}
99 pub struct Nested2(Nested1
, Zst1
);
101 // CHECK: define double @test_Nested2(double %arg0)
103 pub extern fn test_Nested2(_
: Nested2
) -> Nested2 { loop {}
}
106 struct f32x4(f32, f32, f32, f32);
109 pub struct Vector(f32x4
);
111 // CHECK: define <4 x float> @test_Vector(<4 x float> %arg0)
113 pub extern fn test_Vector(_
: Vector
) -> Vector { loop {}
}
115 trait Mirror { type It: ?Sized; }
116 impl<T
: ?Sized
> Mirror
for T { type It = Self; }
119 pub struct StructWithProjection(<f32 as Mirror
>::It
);
121 // CHECK: define float @test_Projection(float %arg0)
123 pub extern fn test_Projection(_
: StructWithProjection
) -> StructWithProjection { loop {}
}
126 // All that remains to be tested are aggregates. They are tested in separate files called repr-
127 // transparent-*.rs with `only-*` or `ignore-*` directives, because the expected LLVM IR
128 // function signatures vary so much that it's not reasonably possible to cover all of them with a
129 // single CHECK line.
131 // You may be wondering why we don't just compare the return types and argument types for equality
132 // with FileCheck regex captures. Well, rustc doesn't perform newtype unwrapping on newtypes
133 // containing aggregates. This is OK on all ABIs we support, but because LLVM has not gotten rid of
134 // pointee types yet, the IR function signature will be syntactically different (%Foo* vs