2022-02-16 23:58:13 -06:00
|
|
|
// compile-flags: -C opt-level=0 -C no-prepopulate-passes
|
|
|
|
|
|
|
|
// This test checks that arguments/returns in opt-level=0 builds,
|
|
|
|
// while lacking attributes used for optimization, still have ABI-affecting attributes.
|
|
|
|
|
|
|
|
#![crate_type = "lib"]
|
|
|
|
#![feature(rustc_attrs)]
|
|
|
|
|
|
|
|
pub struct S {
|
|
|
|
_field: [i32; 8],
|
|
|
|
}
|
|
|
|
|
2022-02-25 18:24:59 -06:00
|
|
|
// CHECK: zeroext i1 @boolean(i1 zeroext %x)
|
2022-02-16 23:58:13 -06:00
|
|
|
#[no_mangle]
|
|
|
|
pub fn boolean(x: bool) -> bool {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @boolean_call
|
|
|
|
#[no_mangle]
|
|
|
|
pub fn boolean_call(x: bool, f: fn(bool) -> bool) -> bool {
|
|
|
|
// CHECK: call zeroext i1 %f(i1 zeroext %x)
|
|
|
|
f(x)
|
|
|
|
}
|
|
|
|
|
2023-07-27 16:44:13 -05:00
|
|
|
// CHECK: align 4 ptr @borrow(ptr align 4 %x)
|
2022-02-16 23:58:13 -06:00
|
|
|
#[no_mangle]
|
|
|
|
pub fn borrow(x: &i32) -> &i32 {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
2023-07-27 16:44:13 -05:00
|
|
|
// CHECK: align 4 ptr @borrow_mut(ptr align 4 %x)
|
2022-12-27 05:31:17 -06:00
|
|
|
#[no_mangle]
|
|
|
|
pub fn borrow_mut(x: &mut i32) -> &mut i32 {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
2022-02-16 23:58:13 -06:00
|
|
|
// CHECK-LABEL: @borrow_call
|
|
|
|
#[no_mangle]
|
|
|
|
pub fn borrow_call(x: &i32, f: fn(&i32) -> &i32) -> &i32 {
|
2023-07-27 16:44:13 -05:00
|
|
|
// CHECK: call align 4 ptr %f(ptr align 4 %x)
|
2022-02-16 23:58:13 -06:00
|
|
|
f(x)
|
|
|
|
}
|
|
|
|
|
2023-07-27 16:44:13 -05:00
|
|
|
// CHECK: void @struct_(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %x)
|
2022-02-16 23:58:13 -06:00
|
|
|
#[no_mangle]
|
|
|
|
pub fn struct_(x: S) -> S {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @struct_call
|
|
|
|
#[no_mangle]
|
|
|
|
pub fn struct_call(x: S, f: fn(S) -> S) -> S {
|
2023-07-27 16:44:13 -05:00
|
|
|
// CHECK: call void %f(ptr sret(%S) align 4{{( %_0)?}}, ptr align 4 %{{.+}})
|
2022-02-16 23:58:13 -06:00
|
|
|
f(x)
|
|
|
|
}
|
|
|
|
|
Separate immediate and in-memory ScalarPair representation
Currently, we assume that ScalarPair is always represented using
a two-element struct, both as an immediate value and when stored
in memory.
This currently works fairly well, but runs into problems with
https://github.com/rust-lang/rust/pull/116672, where a ScalarPair
involving an i128 type can no longer be represented as a two-element
struct in memory. For example, the tuple `(i32, i128)` needs to be
represented in-memory as `{ i32, [3 x i32], i128 }` to satisfy
alignment requirement. Using `{ i32, i128 }` instead will result in
the second element being stored at the wrong offset (prior to
LLVM 18).
Resolve this issue by no longer requiring that the immediate and
in-memory type for ScalarPair are the same. The in-memory type
will now look the same as for normal struct types (and will include
padding filler and similar), while the immediate type stays a
simple two-element struct type. This also means that booleans in
immediate ScalarPair are now represented as i1 rather than i8,
just like we do everywhere else.
The core change here is to llvm_type (which now treats ScalarPair
as a normal struct) and immediate_llvm_type (which returns the
two-element struct that llvm_type used to produce). The rest is
fixing things up to no longer assume these are the same. In
particular, this switches places that try to get pointers to the
ScalarPair elements to use byte-geps instead of struct-geps.
2023-12-15 05:14:39 -06:00
|
|
|
// CHECK: { i1, i8 } @enum_(i1 zeroext %x.0, i8 %x.1)
|
2022-02-16 23:58:13 -06:00
|
|
|
#[no_mangle]
|
|
|
|
pub fn enum_(x: Option<u8>) -> Option<u8> {
|
|
|
|
x
|
|
|
|
}
|
|
|
|
|
|
|
|
// CHECK-LABEL: @enum_call
|
|
|
|
#[no_mangle]
|
|
|
|
pub fn enum_call(x: Option<u8>, f: fn(Option<u8>) -> Option<u8>) -> Option<u8> {
|
Separate immediate and in-memory ScalarPair representation
Currently, we assume that ScalarPair is always represented using
a two-element struct, both as an immediate value and when stored
in memory.
This currently works fairly well, but runs into problems with
https://github.com/rust-lang/rust/pull/116672, where a ScalarPair
involving an i128 type can no longer be represented as a two-element
struct in memory. For example, the tuple `(i32, i128)` needs to be
represented in-memory as `{ i32, [3 x i32], i128 }` to satisfy
alignment requirement. Using `{ i32, i128 }` instead will result in
the second element being stored at the wrong offset (prior to
LLVM 18).
Resolve this issue by no longer requiring that the immediate and
in-memory type for ScalarPair are the same. The in-memory type
will now look the same as for normal struct types (and will include
padding filler and similar), while the immediate type stays a
simple two-element struct type. This also means that booleans in
immediate ScalarPair are now represented as i1 rather than i8,
just like we do everywhere else.
The core change here is to llvm_type (which now treats ScalarPair
as a normal struct) and immediate_llvm_type (which returns the
two-element struct that llvm_type used to produce). The rest is
fixing things up to no longer assume these are the same. In
particular, this switches places that try to get pointers to the
ScalarPair elements to use byte-geps instead of struct-geps.
2023-12-15 05:14:39 -06:00
|
|
|
// CHECK: call { i1, i8 } %f(i1 zeroext %x.0, i8 %x.1)
|
2022-02-16 23:58:13 -06:00
|
|
|
f(x)
|
|
|
|
}
|