mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 21:16:50 +00:00
Put noundef
on all scalars that don't allow uninit
Previously, it was only put on scalars with range validity invariants like bool, was uninit was obviously invalid for those. Since then, we have normatively declared all uninit primitives to be undefined behavior and can therefore put `noundef` on them. The remaining concern was the `mem::uninitialized` function, which cause quite a lot of UB in the older parts of the ecosystem. This function now doesn't return uninit values anymore, making users of it safe from this change. The only real sources of UB where people could encounter uninit primitives are `MaybeUninit::uninit().assume_init()`, which has always be clear in the docs about being UB and from heap allocations (like reading from the spare capacity of a vec. This is hopefully rare enough to not break anything.
This commit is contained in:
parent
4781233a77
commit
645c0fddd2
@ -501,7 +501,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
||||
layout: TyAndLayout<'tcx>,
|
||||
offset: Size,
|
||||
) {
|
||||
if !scalar.is_always_valid(bx) {
|
||||
if !scalar.is_uninit_valid() {
|
||||
bx.noundef_metadata(load);
|
||||
}
|
||||
|
||||
|
@ -220,7 +220,7 @@ fn adjust_for_rust_scalar<'tcx>(
|
||||
}
|
||||
|
||||
// Scalars which have invalid values cannot be undef.
|
||||
if !scalar.is_always_valid(&cx) {
|
||||
if !scalar.is_uninit_valid() {
|
||||
attrs.set(ArgAttribute::NoUndef);
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ trait Sized {}
|
||||
trait Copy {}
|
||||
impl Copy for i64 {}
|
||||
|
||||
// CHECK: define x86_64_sysvcc i64 @has_sysv64_abi
|
||||
// CHECK: define x86_64_sysvcc noundef i64 @has_sysv64_abi
|
||||
#[no_mangle]
|
||||
pub extern "sysv64" fn has_sysv64_abi(a: i64) -> i64 {
|
||||
a
|
||||
|
@ -15,7 +15,7 @@ trait Sized {}
|
||||
trait Copy {}
|
||||
impl Copy for i64 {}
|
||||
|
||||
// CHECK: define x86_intrcc i64 @has_x86_interrupt_abi
|
||||
// CHECK: define x86_intrcc noundef i64 @has_x86_interrupt_abi
|
||||
#[no_mangle]
|
||||
pub extern "x86-interrupt" fn has_x86_interrupt_abi(a: i64) -> i64 {
|
||||
a
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Hack to get the correct size for the length part in slices
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn helper(_: usize) {
|
||||
}
|
||||
|
@ -31,4 +31,4 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
|
||||
// Hide the LLVM 15+ `allocalign` attribute in the declaration of __rust_alloc
|
||||
// from the CHECK-NOT above. We don't check the attributes here because we can't rely
|
||||
// on all of them being set until LLVM 15.
|
||||
// CHECK: declare noalias{{.*}} @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+.*}})
|
||||
// CHECK: declare noalias{{.*}} @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+.*}} noundef)
|
||||
|
@ -28,6 +28,6 @@ pub fn box_uninitialized2() -> Box<MaybeUninit<[usize; 1024 * 1024]>> {
|
||||
|
||||
// Hide the `allocalign` attribute in the declaration of __rust_alloc
|
||||
// from the CHECK-NOT above, and also verify the attributes got set reasonably.
|
||||
// CHECK: declare noalias ptr @__rust_alloc(i{{[0-9]+}}, i{{[0-9]+}} allocalign) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
|
||||
// CHECK: declare noalias noundef ptr @__rust_alloc(i{{[0-9]+}} noundef, i{{[0-9]+}} allocalign noundef) unnamed_addr [[RUST_ALLOC_ATTRS:#[0-9]+]]
|
||||
|
||||
// CHECK-DAG: attributes [[RUST_ALLOC_ATTRS]] = { {{.*}} allockind("alloc,uninitialized,aligned") allocsize(0) uwtable "alloc-family"="__rust_alloc" {{.*}} }
|
||||
|
@ -15,7 +15,7 @@ extern "C" {
|
||||
|
||||
pub unsafe extern "C" fn use_foreign_c_variadic_0() {
|
||||
// Ensure that we correctly call foreign C-variadic functions.
|
||||
// CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM:i32( signext)?]] 0)
|
||||
// CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM:i32 noundef( signext)?]] 0)
|
||||
foreign_c_variadic_0(0);
|
||||
// CHECK: call void (i32, ...) @foreign_c_variadic_0([[PARAM]] 0, [[PARAM]] 42)
|
||||
foreign_c_variadic_0(0, 42i32);
|
||||
@ -61,7 +61,7 @@ pub unsafe extern "C" fn c_variadic(n: i32, mut ap: ...) -> i32 {
|
||||
// Ensure that we generate the correct `call` signature when calling a Rust
|
||||
// defined C-variadic.
|
||||
pub unsafe fn test_c_variadic_call() {
|
||||
// CHECK: call [[RET:(signext )?i32]] (i32, ...) @c_variadic([[PARAM]] 0)
|
||||
// CHECK: call [[RET:noundef( signext)? i32]] (i32, ...) @c_variadic([[PARAM]] 0)
|
||||
c_variadic(0);
|
||||
// CHECK: call [[RET]] (i32, ...) @c_variadic([[PARAM]] 0, [[PARAM]] 42)
|
||||
c_variadic(0, 42i32);
|
||||
|
@ -23,7 +23,7 @@ pub fn do_call() {
|
||||
|
||||
unsafe {
|
||||
// Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them
|
||||
// CHECK: call float @llvm.sqrt.f32(float 4.000000e+00
|
||||
// CHECK: call noundef float @llvm.sqrt.f32(float noundef 4.000000e+00
|
||||
sqrt(4.0);
|
||||
}
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ use std::cmp::Ordering;
|
||||
pub struct Foo(u16);
|
||||
|
||||
// CHECK-LABEL: @check_lt
|
||||
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
|
||||
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
|
||||
#[no_mangle]
|
||||
pub fn check_lt(a: Foo, b: Foo) -> bool {
|
||||
// CHECK: %[[R:.+]] = icmp ult i16 %[[A]], %[[B]]
|
||||
@ -22,7 +22,7 @@ pub fn check_lt(a: Foo, b: Foo) -> bool {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_le
|
||||
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
|
||||
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
|
||||
#[no_mangle]
|
||||
pub fn check_le(a: Foo, b: Foo) -> bool {
|
||||
// CHECK: %[[R:.+]] = icmp ule i16 %[[A]], %[[B]]
|
||||
@ -31,7 +31,7 @@ pub fn check_le(a: Foo, b: Foo) -> bool {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_gt
|
||||
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
|
||||
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
|
||||
#[no_mangle]
|
||||
pub fn check_gt(a: Foo, b: Foo) -> bool {
|
||||
// CHECK: %[[R:.+]] = icmp ugt i16 %[[A]], %[[B]]
|
||||
@ -40,7 +40,7 @@ pub fn check_gt(a: Foo, b: Foo) -> bool {
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @check_ge
|
||||
// CHECK-SAME: (i16 %[[A:.+]], i16 %[[B:.+]])
|
||||
// CHECK-SAME: (i16 noundef %[[A:.+]], i16 noundef %[[B:.+]])
|
||||
#[no_mangle]
|
||||
pub fn check_ge(a: Foo, b: Foo) -> bool {
|
||||
// CHECK: %[[R:.+]] = icmp uge i16 %[[A]], %[[B]]
|
||||
|
@ -11,7 +11,7 @@ pub enum Enum0 {
|
||||
B,
|
||||
}
|
||||
|
||||
// CHECK: define i8 @match0{{.*}}
|
||||
// CHECK: define noundef i8 @match0{{.*}}
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: %1 = icmp eq i8 %0, 2
|
||||
// CHECK-NEXT: %2 = and i8 %0, 1
|
||||
@ -32,7 +32,7 @@ pub enum Enum1 {
|
||||
C,
|
||||
}
|
||||
|
||||
// CHECK: define i8 @match1{{.*}}
|
||||
// CHECK: define noundef i8 @match1{{.*}}
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: [[DISCR:%.*]] = {{.*}}call i8 @llvm.usub.sat.i8(i8 %0, i8 1)
|
||||
// CHECK-NEXT: switch i8 [[DISCR]], label {{.*}} [
|
||||
@ -88,7 +88,7 @@ pub enum Enum2 {
|
||||
E,
|
||||
}
|
||||
|
||||
// CHECK: define i8 @match2{{.*}}
|
||||
// CHECK: define noundef i8 @match2{{.*}}
|
||||
// CHECK-NEXT: start:
|
||||
// CHECK-NEXT: %1 = add i8 %0, 2
|
||||
// CHECK-NEXT: %2 = zext i8 %1 to i64
|
||||
|
@ -15,27 +15,27 @@ trait Sized {}
|
||||
trait Copy {}
|
||||
|
||||
pub mod tests {
|
||||
// CHECK: @f1(i32 inreg %_1, i32 inreg %_2, i32 %_3)
|
||||
// CHECK: @f1(i32 inreg noundef %_1, i32 inreg noundef %_2, i32 noundef %_3)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f1(_: i32, _: i32, _: i32) {}
|
||||
|
||||
// CHECK: @f2({{i32\*|ptr}} inreg %_1, {{i32\*|ptr}} inreg %_2, {{i32\*|ptr}} %_3)
|
||||
// CHECK: @f2({{i32\*|ptr}} inreg noundef %_1, {{i32\*|ptr}} inreg noundef %_2, {{i32\*|ptr}} noundef %_3)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f2(_: *const i32, _: *const i32, _: *const i32) {}
|
||||
|
||||
// CHECK: @f3(float %_1, i32 inreg %_2, i32 inreg %_3, i32 %_4)
|
||||
// CHECK: @f3(float noundef %_1, i32 inreg noundef %_2, i32 inreg noundef %_3, i32 noundef %_4)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f3(_: f32, _: i32, _: i32, _: i32) {}
|
||||
|
||||
// CHECK: @f4(i32 inreg %_1, float %_2, i32 inreg %_3, i32 %_4)
|
||||
// CHECK: @f4(i32 inreg noundef %_1, float noundef %_2, i32 inreg noundef %_3, i32 noundef %_4)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f4(_: i32, _: f32, _: i32, _: i32) {}
|
||||
|
||||
// CHECK: @f5(i64 %_1, i32 %_2)
|
||||
// CHECK: @f5(i64 noundef %_1, i32 noundef %_2)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f5(_: i64, _: i32) {}
|
||||
|
||||
// CHECK: @f6(i1 inreg noundef zeroext %_1, i32 inreg %_2, i32 %_3)
|
||||
// CHECK: @f6(i1 inreg noundef zeroext %_1, i32 inreg noundef %_2, i32 noundef %_3)
|
||||
#[no_mangle]
|
||||
pub extern "fastcall" fn f6(_: bool, _: i32, _: i32) {}
|
||||
}
|
||||
|
@ -7,11 +7,11 @@
|
||||
|
||||
#[no_mangle]
|
||||
pub fn sum(x: u32, y: u32) -> u32 {
|
||||
// YES-LABEL: define{{.*}}i32 @sum(i32 %0, i32 %1)
|
||||
// YES-LABEL: define{{.*}}i32 @sum(i32 noundef %0, i32 noundef %1)
|
||||
// YES-NEXT: %3 = add i32 %1, %0
|
||||
// YES-NEXT: ret i32 %3
|
||||
|
||||
// NO-LABEL: define{{.*}}i32 @sum(i32 %x, i32 %y)
|
||||
// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
|
||||
// NO-NEXT: start:
|
||||
// NO-NEXT: %z = add i32 %y, %x
|
||||
// NO-NEXT: ret i32 %z
|
||||
|
@ -20,7 +20,7 @@ trait Copy { }
|
||||
impl Copy for u32 {}
|
||||
|
||||
|
||||
// CHECK: define i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] {
|
||||
// CHECK: define noundef i32 @peach{{.*}}[[PEACH_ATTRS:\#[0-9]+]] {
|
||||
#[no_mangle]
|
||||
pub fn peach(x: u32) -> u32 {
|
||||
x
|
||||
|
@ -61,7 +61,7 @@ pub fn maybeuninit_char(x: MaybeUninit<char>) -> MaybeUninit<char> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: i64 @int(i64 %x)
|
||||
// CHECK: noundef i64 @int(i64 noundef %x)
|
||||
#[no_mangle]
|
||||
pub fn int(x: u64) -> u64 {
|
||||
x
|
||||
@ -73,7 +73,7 @@ pub fn nonzero_int(x: NonZeroU64) -> NonZeroU64 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: i64 @option_nonzero_int(i64 %x)
|
||||
// CHECK: noundef i64 @option_nonzero_int(i64 noundef %x)
|
||||
#[no_mangle]
|
||||
pub fn option_nonzero_int(x: Option<NonZeroU64>) -> Option<NonZeroU64> {
|
||||
x
|
||||
@ -138,7 +138,7 @@ pub fn indirect_struct(_: S) {
|
||||
pub fn borrowed_struct(_: &S) {
|
||||
}
|
||||
|
||||
// CHECK: @raw_struct({{%S\*|ptr}} %_1)
|
||||
// CHECK: @raw_struct({{%S\*|ptr}} noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn raw_struct(_: *const S) {
|
||||
}
|
||||
@ -160,35 +160,35 @@ pub fn struct_return() -> S {
|
||||
}
|
||||
|
||||
// Hack to get the correct size for the length part in slices
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn helper(_: usize) {
|
||||
}
|
||||
|
||||
// CHECK: @slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
|
||||
// CHECK: @slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn slice(_: &[u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @mutable_slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull align 1 %_1.0, [[USIZE]] %_1.1)
|
||||
// CHECK: @mutable_slice({{\[0 x i8\]\*|ptr}} noalias noundef nonnull align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn mutable_slice(_: &mut [u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @unsafe_slice({{\[0 x i16\]\*|ptr}} noundef nonnull align 2 %_1.0, [[USIZE]] %_1.1)
|
||||
// CHECK: @unsafe_slice({{\[0 x i16\]\*|ptr}} noundef nonnull align 2 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// unsafe interior means this isn't actually readonly and there may be aliases ...
|
||||
#[no_mangle]
|
||||
pub fn unsafe_slice(_: &[UnsafeInner]) {
|
||||
}
|
||||
|
||||
// CHECK: @raw_slice({{\[0 x i8\]\*|ptr}} %_1.0, [[USIZE]] %_1.1)
|
||||
// CHECK: @raw_slice({{\[0 x i8\]\*|ptr}} noundef %_1.0, [[USIZE]] noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn raw_slice(_: *const [u8]) {
|
||||
}
|
||||
|
||||
// CHECK: @str({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] %_1.1)
|
||||
// CHECK: @str({{\[0 x i8\]\*|ptr}} noalias noundef nonnull readonly align 1 %_1.0, [[USIZE]] noundef %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn str(_: &[u8]) {
|
||||
@ -197,26 +197,26 @@ pub fn str(_: &[u8]) {
|
||||
// CHECK: @trait_borrow({{\{\}\*|ptr}} noundef nonnull align 1 %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
// FIXME #25759 This should also have `nocapture`
|
||||
#[no_mangle]
|
||||
pub fn trait_borrow(_: &Drop) {
|
||||
pub fn trait_borrow(_: &dyn Drop) {
|
||||
}
|
||||
|
||||
// CHECK: @trait_raw({{\{\}\*|ptr}} %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
// CHECK: @trait_raw({{\{\}\*|ptr}} noundef %_1.0, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn trait_raw(_: *const Drop) {
|
||||
pub fn trait_raw(_: *const dyn Drop) {
|
||||
}
|
||||
|
||||
// CHECK: @trait_box({{\{\}\*|ptr}} noalias noundef nonnull align 1{{( %0)?}}, {{.+}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}){{( %1)?}})
|
||||
#[no_mangle]
|
||||
pub fn trait_box(_: Box<Drop>) {
|
||||
pub fn trait_box(_: Box<dyn Drop>) {
|
||||
}
|
||||
|
||||
// CHECK: { {{i8\*|ptr}}, {{i8\*|ptr}} } @trait_option({{i8\*|ptr}} noalias noundef align 1 %x.0, {{i8\*|ptr}} %x.1)
|
||||
#[no_mangle]
|
||||
pub fn trait_option(x: Option<Box<Drop>>) -> Option<Box<Drop>> {
|
||||
pub fn trait_option(x: Option<Box<dyn Drop>>) -> Option<Box<dyn Drop>> {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: { {{\[0 x i16\]\*|ptr}}, [[USIZE]] } @return_slice({{\[0 x i16\]\*|ptr}} noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] %x.1)
|
||||
// CHECK: { {{\[0 x i16\]\*|ptr}}, [[USIZE]] } @return_slice({{\[0 x i16\]\*|ptr}} noalias noundef nonnull readonly align 2 %x.0, [[USIZE]] noundef %x.1)
|
||||
#[no_mangle]
|
||||
pub fn return_slice(x: &[u16]) -> &[u16] {
|
||||
x
|
||||
|
@ -13,6 +13,6 @@ pub fn hi(n: i32) -> i32 { n }
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn hey() {
|
||||
// CHECK: call i32 @hi(i32
|
||||
// CHECK: call noundef i32 @hi(i32
|
||||
const_eval_select((42,), foo, hi);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
// CHECK-LABEL: @mask_ptr
|
||||
// CHECK-SAME: [[WORD:i[0-9]+]] %mask
|
||||
// CHECK-SAME: [[WORD:i[0-9]+]] noundef %mask
|
||||
#[no_mangle]
|
||||
pub fn mask_ptr(ptr: *const u16, mask: usize) -> *const u16 {
|
||||
// CHECK: call
|
||||
|
@ -5,7 +5,7 @@
|
||||
#[no_mangle]
|
||||
pub struct F32(f32);
|
||||
|
||||
// CHECK: define{{.*}}float @add_newtype_f32(float %a, float %b)
|
||||
// CHECK: define{{.*}}float @add_newtype_f32(float noundef %a, float noundef %b)
|
||||
#[inline(never)]
|
||||
#[no_mangle]
|
||||
pub fn add_newtype_f32(a: F32, b: F32) -> F32 {
|
||||
@ -15,7 +15,7 @@ pub fn add_newtype_f32(a: F32, b: F32) -> F32 {
|
||||
#[no_mangle]
|
||||
pub struct F64(f64);
|
||||
|
||||
// CHECK: define{{.*}}double @add_newtype_f64(double %a, double %b)
|
||||
// CHECK: define{{.*}}double @add_newtype_f64(double noundef %a, double noundef %b)
|
||||
#[inline(never)]
|
||||
#[no_mangle]
|
||||
pub fn add_newtype_f64(a: F64, b: F64) -> F64 {
|
||||
|
@ -16,6 +16,6 @@ struct Bar(u64, u64, u64);
|
||||
|
||||
// Ensure that emit arguments of the correct type.
|
||||
pub unsafe fn test_call_variadic() {
|
||||
// CHECK: call void (i32, ...) @variadic_fn(i32 0, i8 {{.*}}, {{%Bar\*|ptr}} {{.*}})
|
||||
// CHECK: call void (i32, ...) @variadic_fn(i32 noundef 0, i8 {{.*}}, {{%Bar\*|ptr}} {{.*}})
|
||||
variadic_fn(0, Foo(0), Bar(0, 0, 0))
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ pub fn load_scalar_pair<'a>(x: &(&'a i32, &'a Align16)) -> (&'a i32, &'a Align16
|
||||
#[no_mangle]
|
||||
pub fn load_raw_pointer<'a>(x: &*const i32) -> *const i32 {
|
||||
// loaded raw pointer should not have !nonnull, !align, or !noundef metadata
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]]{{$}}
|
||||
// CHECK: load {{i32\*|ptr}}, {{i32\*\*|ptr}} %x, align [[PTR_ALIGNMENT]], !noundef !2{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
@ -93,7 +93,7 @@ pub fn load_maybeuninit_enum_bool(x: &MaybeUninit<MyBool>) -> MaybeUninit<MyBool
|
||||
// CHECK-LABEL: @load_int
|
||||
#[no_mangle]
|
||||
pub fn load_int(x: &u16) -> u16 {
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef !2{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
@ -107,7 +107,7 @@ pub fn load_nonzero_int(x: &NonZeroU16) -> NonZeroU16 {
|
||||
// CHECK-LABEL: @load_option_nonzero_int
|
||||
#[no_mangle]
|
||||
pub fn load_option_nonzero_int(x: &Option<NonZeroU16>) -> Option<NonZeroU16> {
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2{{$}}
|
||||
// CHECK: load i16, {{i16\*|ptr}} %x, align 2, !noundef !2{{$}}
|
||||
*x
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ pub unsafe extern "C" fn naked_empty() {
|
||||
}
|
||||
|
||||
// CHECK: Function Attrs: naked
|
||||
// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 %a, i64 %b)
|
||||
// CHECK-NEXT: define{{.*}}i{{[0-9]+}} @naked_with_args_and_return(i64 noundef %a, i64 noundef %b)
|
||||
#[no_mangle]
|
||||
#[naked]
|
||||
pub unsafe extern "C" fn naked_with_args_and_return(a: isize, b: isize) -> isize {
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#![crate_type = "rlib"]
|
||||
|
||||
// CHECK: define i8 @call_foreign_fn()
|
||||
// CHECK: define noundef i8 @call_foreign_fn()
|
||||
#[no_mangle]
|
||||
pub fn call_foreign_fn() -> u8 {
|
||||
unsafe {
|
||||
@ -13,7 +13,7 @@ pub fn call_foreign_fn() -> u8 {
|
||||
// (Allow but do not require `zeroext` here, because it is not worth effort to
|
||||
// spell out which targets have it and which ones do not; see rust#97800.)
|
||||
|
||||
// CHECK: declare{{( zeroext)?}} i8 @foreign_fn()
|
||||
// CHECK: declare noundef{{( zeroext)?}} i8 @foreign_fn()
|
||||
extern "C" {fn foreign_fn() -> u8;}
|
||||
|
||||
// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// With PIE we know local functions cannot be interpositioned, we can mark them
|
||||
// as dso_local.
|
||||
// CHECK: define dso_local i8 @call_foreign_fn()
|
||||
// CHECK: define dso_local noundef i8 @call_foreign_fn()
|
||||
#[no_mangle]
|
||||
pub fn call_foreign_fn() -> u8 {
|
||||
unsafe {
|
||||
@ -15,7 +15,7 @@ pub fn call_foreign_fn() -> u8 {
|
||||
|
||||
// External functions are still marked as non-dso_local, since we don't know if the symbol
|
||||
// is defined in the binary or in the shared library.
|
||||
// CHECK: declare zeroext i8 @foreign_fn()
|
||||
// CHECK: declare noundef zeroext i8 @foreign_fn()
|
||||
extern "C" {fn foreign_fn() -> u8;}
|
||||
|
||||
// CHECK: !{i32 {{[78]}}, !"PIC Level", i32 2}
|
||||
|
@ -3,7 +3,7 @@
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// Hack to get the correct size for the length part in slices
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn helper(_: usize) {
|
||||
}
|
||||
|
@ -18,21 +18,21 @@ pub struct Zst2(());
|
||||
#[repr(transparent)]
|
||||
pub struct F32(f32);
|
||||
|
||||
// CHECK: define{{.*}}float @test_F32(float %_1)
|
||||
// CHECK: define{{.*}}float @test_F32(float noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_F32(_: F32) -> F32 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Ptr(*mut u8);
|
||||
|
||||
// CHECK: define{{.*}}{{i8\*|ptr}} @test_Ptr({{i8\*|ptr}} %_1)
|
||||
// CHECK: define{{.*}}{{i8\*|ptr}} @test_Ptr({{i8\*|ptr}} noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Ptr(_: Ptr) -> Ptr { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct WithZst(u64, Zst1);
|
||||
|
||||
// CHECK: define{{.*}}i64 @test_WithZst(i64 %_1)
|
||||
// CHECK: define{{.*}}i64 @test_WithZst(i64 noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
|
||||
|
||||
@ -40,14 +40,14 @@ pub extern "C" fn test_WithZst(_: WithZst) -> WithZst { loop {} }
|
||||
pub struct WithZeroSizedArray(*const f32, [i8; 0]);
|
||||
|
||||
// Apparently we use i32* when newtype-unwrapping f32 pointers. Whatever.
|
||||
// CHECK: define{{.*}}{{i32\*|ptr}} @test_WithZeroSizedArray({{i32\*|ptr}} %_1)
|
||||
// CHECK: define{{.*}}{{i32\*|ptr}} @test_WithZeroSizedArray({{i32\*|ptr}} noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_WithZeroSizedArray(_: WithZeroSizedArray) -> WithZeroSizedArray { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Generic<T>(T);
|
||||
|
||||
// CHECK: define{{.*}}double @test_Generic(double %_1)
|
||||
// CHECK: define{{.*}}double @test_Generic(double noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Generic(_: Generic<f64>) -> Generic<f64> { loop {} }
|
||||
|
||||
@ -64,7 +64,7 @@ pub extern "C" fn test_Gpz(_: GenericPlusZst<Bool>) -> GenericPlusZst<Bool> { lo
|
||||
#[repr(transparent)]
|
||||
pub struct LifetimePhantom<'a, T: 'a>(*const T, PhantomData<&'a T>);
|
||||
|
||||
// CHECK: define{{.*}}{{i16\*|ptr}} @test_LifetimePhantom({{i16\*|ptr}} %_1)
|
||||
// CHECK: define{{.*}}{{i16\*|ptr}} @test_LifetimePhantom({{i16\*|ptr}} noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_LifetimePhantom(_: LifetimePhantom<i16>) -> LifetimePhantom<i16> { loop {} }
|
||||
|
||||
@ -74,28 +74,28 @@ pub struct UnitPhantom<T, U> { val: T, unit: PhantomData<U> }
|
||||
|
||||
pub struct Px;
|
||||
|
||||
// CHECK: define{{.*}}float @test_UnitPhantom(float %_1)
|
||||
// CHECK: define{{.*}}float @test_UnitPhantom(float noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_UnitPhantom(_: UnitPhantom<f32, Px>) -> UnitPhantom<f32, Px> { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct TwoZsts(Zst1, i8, Zst2);
|
||||
|
||||
// CHECK: define{{( dso_local)?}}{{( signext)?}} i8 @test_TwoZsts(i8{{( signext)?}} %_1)
|
||||
// CHECK: define{{( dso_local)?}} noundef{{( signext)?}} i8 @test_TwoZsts(i8 noundef{{( signext)?}} %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_TwoZsts(_: TwoZsts) -> TwoZsts { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Nested1(Zst2, Generic<f64>);
|
||||
|
||||
// CHECK: define{{.*}}double @test_Nested1(double %_1)
|
||||
// CHECK: define{{.*}}double @test_Nested1(double noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Nested1(_: Nested1) -> Nested1 { loop {} }
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Nested2(Nested1, Zst1);
|
||||
|
||||
// CHECK: define{{.*}}double @test_Nested2(double %_1)
|
||||
// CHECK: define{{.*}}double @test_Nested2(double noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 { loop {} }
|
||||
|
||||
@ -115,7 +115,7 @@ impl<T: ?Sized> Mirror for T { type It = Self; }
|
||||
#[repr(transparent)]
|
||||
pub struct StructWithProjection(<f32 as Mirror>::It);
|
||||
|
||||
// CHECK: define{{.*}}float @test_Projection(float %_1)
|
||||
// CHECK: define{{.*}}float @test_Projection(float noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_Projection(_: StructWithProjection) -> StructWithProjection { loop {} }
|
||||
|
||||
@ -124,7 +124,7 @@ pub enum EnumF32 {
|
||||
Variant(F32)
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}float @test_EnumF32(float %_1)
|
||||
// CHECK: define{{.*}}float @test_EnumF32(float noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_EnumF32(_: EnumF32) -> EnumF32 { loop {} }
|
||||
|
||||
@ -133,7 +133,7 @@ pub enum EnumF32WithZsts {
|
||||
Variant(Zst1, F32, Zst2)
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}float @test_EnumF32WithZsts(float %_1)
|
||||
// CHECK: define{{.*}}float @test_EnumF32WithZsts(float noundef %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_EnumF32WithZsts(_: EnumF32WithZsts) -> EnumF32WithZsts { loop {} }
|
||||
|
||||
@ -142,7 +142,7 @@ pub union UnionF32 {
|
||||
field: F32,
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}float @test_UnionF32(float %_1)
|
||||
// CHECK: define{{.*}} float @test_UnionF32(float %_1)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn test_UnionF32(_: UnionF32) -> UnionF32 { loop {} }
|
||||
|
||||
|
@ -29,25 +29,25 @@ pub extern "C" fn f_scalar_0(a: bool) -> bool {
|
||||
a
|
||||
}
|
||||
|
||||
// CHECK: define signext i8 @f_scalar_1(i8 signext %x)
|
||||
// CHECK: define noundef signext i8 @f_scalar_1(i8 noundef signext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_1(x: i8) -> i8 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define zeroext i8 @f_scalar_2(i8 zeroext %x)
|
||||
// CHECK: define noundef zeroext i8 @f_scalar_2(i8 noundef zeroext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_2(x: u8) -> u8 {
|
||||
x
|
||||
}
|
||||
|
||||
// CHECK: define signext i32 @f_scalar_3(i32 signext %x)
|
||||
// CHECK: define noundef signext i32 @f_scalar_3(i32 noundef signext %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_3(x: i32) -> u32 {
|
||||
x as u32
|
||||
}
|
||||
|
||||
// CHECK: define i64 @f_scalar_4(i64 %x)
|
||||
// CHECK: define noundef i64 @f_scalar_4(i64 noundef %x)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_4(x: i64) -> i64 {
|
||||
x
|
||||
@ -132,13 +132,13 @@ pub struct Large {
|
||||
pub extern "C" fn f_agg_large(mut x: Large) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_agg_large_ret({{%Large\*|ptr}} {{.*}}sret{{.*}}, i32 signext %i, i8 signext %j)
|
||||
// CHECK: define void @f_agg_large_ret({{%Large\*|ptr}} {{.*}}sret{{.*}}, i32 noundef signext %i, i8 noundef signext %j)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_agg_large_ret(i: i32, j: i8) -> Large {
|
||||
Large { a: 1, b: 2, c: 3, d: 4 }
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, {{%Large\*|ptr}} {{.*}}%d, i8 zeroext %e, i8 signext %f, i8 %g, i8 %h)
|
||||
// CHECK: define void @f_scalar_stack_1(i64 %0, [2 x i64] %1, i128 %2, {{%Large\*|ptr}} {{.*}}%d, i8 noundef zeroext %e, i8 noundef signext %f, i8 noundef %g, i8 noundef %h)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_1(
|
||||
a: Tiny,
|
||||
@ -152,7 +152,7 @@ pub extern "C" fn f_scalar_stack_1(
|
||||
) {
|
||||
}
|
||||
|
||||
// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %0, i64 %a, i128 %1, i128 %2, i64 %d, i8 zeroext %e, i8 %f, i8 %g)
|
||||
// CHECK: define void @f_scalar_stack_2({{%Large\*|ptr}} {{.*}}sret{{.*}} %0, i64 noundef %a, i128 %1, i128 %2, i64 noundef %d, i8 noundef zeroext %e, i8 noundef %f, i8 noundef %g)
|
||||
#[no_mangle]
|
||||
pub extern "C" fn f_scalar_stack_2(
|
||||
a: u64,
|
||||
@ -172,7 +172,7 @@ extern "C" {
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f_va_caller() {
|
||||
// CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i64 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, {{%Large\*|ptr}} {{.*}})
|
||||
// CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i64 noundef 3, double {{.*}}, double {{.*}}, i64 {{.*}}, [2 x i64] {{.*}}, i128 {{.*}}, {{%Large\*|ptr}} {{.*}})
|
||||
f_va_callee(
|
||||
1,
|
||||
2i32,
|
||||
@ -184,6 +184,6 @@ pub unsafe extern "C" fn f_va_caller() {
|
||||
SmallAligned { a: 11 },
|
||||
Large { a: 12, b: 13, c: 14, d: 15 },
|
||||
);
|
||||
// CHECK: call signext i32 (i32, ...) @f_va_callee(i32 signext 1, i32 signext 2, i32 signext 3, i32 signext 4, i128 {{.*}}, i32 signext 6, i32 signext 7, i32 8, i32 9)
|
||||
// CHECK: call noundef signext i32 (i32, ...) @f_va_callee(i32 noundef signext 1, i32 noundef signext 2, i32 noundef signext 3, i32 noundef signext 4, i128 {{.*}}, i32 noundef signext 6, i32 noundef signext 7, i32 noundef 8, i32 noundef 9)
|
||||
f_va_callee(1, 2i32, 3i32, 4i32, SmallAligned { a: 5 }, 6i32, 7i32, 8i32, 9i32);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK: [[TT:%.+]] = call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"{{[[:print:]]+}}")
|
||||
// CHECK-NEXT: br i1 [[TT]], label %type_test.pass, label %type_test.fail
|
||||
// CHECK: type_test.pass:
|
||||
// CHECK-NEXT: {{%.+}} = call i32 %f(i32 %arg)
|
||||
// CHECK-NEXT: {{%.+}} = call noundef i32 %f(i32 noundef %arg)
|
||||
// CHECK-NEXT: br label %bb1
|
||||
// CHECK: type_test.fail:
|
||||
// CHECK-NEXT: call void @llvm.trap()
|
||||
|
@ -21,21 +21,21 @@ impl Copy for i32 {}
|
||||
pub fn foo(f: fn(i32) -> i32, arg: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}foo
|
||||
// CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE1:[0-9]+]]
|
||||
// CHECK: call i32 %f(i32 %arg){{.*}}[ "kcfi"(i32 -1666898348) ]
|
||||
// CHECK: call noundef i32 %f(i32 noundef %arg){{.*}}[ "kcfi"(i32 -1666898348) ]
|
||||
f(arg)
|
||||
}
|
||||
|
||||
pub fn bar(f: fn(i32, i32) -> i32, arg1: i32, arg2: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}bar
|
||||
// CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE2:[0-9]+]]
|
||||
// CHECK: call i32 %f(i32 %arg1, i32 %arg2){{.*}}[ "kcfi"(i32 -1789026986) ]
|
||||
// CHECK: call noundef i32 %f(i32 noundef %arg1, i32 noundef %arg2){{.*}}[ "kcfi"(i32 -1789026986) ]
|
||||
f(arg1, arg2)
|
||||
}
|
||||
|
||||
pub fn baz(f: fn(i32, i32, i32) -> i32, arg1: i32, arg2: i32, arg3: i32) -> i32 {
|
||||
// CHECK-LABEL: define{{.*}}baz
|
||||
// CHECK-SAME: {{.*}}!{{<unknown kind #36>|kcfi_type}} ![[TYPE3:[0-9]+]]
|
||||
// CHECK: call i32 %f(i32 %arg1, i32 %arg2, i32 %arg3){{.*}}[ "kcfi"(i32 1248878270) ]
|
||||
// CHECK: call noundef i32 %f(i32 noundef %arg1, i32 noundef %arg2, i32 noundef %arg3){{.*}}[ "kcfi"(i32 1248878270) ]
|
||||
f(arg1, arg2, arg3)
|
||||
}
|
||||
|
||||
|
@ -16,27 +16,27 @@
|
||||
// MSAN-RECOVER: @__msan_keep_going = weak_odr {{.*}}constant i32 1
|
||||
// MSAN-RECOVER-LTO: @__msan_keep_going = weak_odr {{.*}}constant i32 1
|
||||
|
||||
// ASAN-LABEL: define dso_local i32 @penguin(
|
||||
// ASAN-LABEL: define dso_local noundef i32 @penguin(
|
||||
// ASAN: call void @__asan_report_load4(i64 %0)
|
||||
// ASAN: unreachable
|
||||
// ASAN: }
|
||||
//
|
||||
// ASAN-RECOVER-LABEL: define dso_local i32 @penguin(
|
||||
// ASAN-RECOVER-LABEL: define dso_local noundef i32 @penguin(
|
||||
// ASAN-RECOVER: call void @__asan_report_load4_noabort(
|
||||
// ASAN-RECOVER-NOT: unreachable
|
||||
// ASAN: }
|
||||
//
|
||||
// MSAN-LABEL: define dso_local i32 @penguin(
|
||||
// MSAN-LABEL: define dso_local noundef i32 @penguin(
|
||||
// MSAN: call void @__msan_warning{{(_with_origin_noreturn\(i32 0\)|_noreturn\(\))}}
|
||||
// MSAN: unreachable
|
||||
// MSAN: }
|
||||
//
|
||||
// MSAN-RECOVER-LABEL: define dso_local i32 @penguin(
|
||||
// MSAN-RECOVER-LABEL: define dso_local noundef i32 @penguin(
|
||||
// MSAN-RECOVER: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}}
|
||||
// MSAN-RECOVER-NOT: unreachable
|
||||
// MSAN-RECOVER: }
|
||||
//
|
||||
// MSAN-RECOVER-LTO-LABEL: define dso_local i32 @penguin(
|
||||
// MSAN-RECOVER-LTO-LABEL: define dso_local noundef i32 @penguin(
|
||||
// MSAN-RECOVER-LTO: call void @__msan_warning{{(_with_origin\(i32 0\)|\(\))}}
|
||||
// MSAN-RECOVER-LTO-NOT: unreachable
|
||||
// MSAN-RECOVER-LTO: }
|
||||
|
@ -8,13 +8,13 @@ pub fn pair_bool_bool(pair: (bool, bool)) -> (bool, bool) {
|
||||
pair
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}{ i8, i32 } @pair_bool_i32(i1 noundef zeroext %pair.0, i32 %pair.1)
|
||||
// CHECK: define{{.*}}{ i8, i32 } @pair_bool_i32(i1 noundef zeroext %pair.0, i32 noundef %pair.1)
|
||||
#[no_mangle]
|
||||
pub fn pair_bool_i32(pair: (bool, i32)) -> (bool, i32) {
|
||||
pair
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}{ i32, i8 } @pair_i32_bool(i32 %pair.0, i1 noundef zeroext %pair.1)
|
||||
// CHECK: define{{.*}}{ i32, i8 } @pair_i32_bool(i32 noundef %pair.0, i1 noundef zeroext %pair.1)
|
||||
#[no_mangle]
|
||||
pub fn pair_i32_bool(pair: (i32, bool)) -> (i32, bool) {
|
||||
pair
|
||||
|
@ -31,85 +31,85 @@
|
||||
// The patterns in this file are written in the style of a table to make the
|
||||
// uniformities and distinctions more apparent.
|
||||
//
|
||||
// ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING
|
||||
// ============================== =======================
|
||||
// x86_64: void @c_arg_u8(i8 zeroext %_a)
|
||||
// i686: void @c_arg_u8(i8 zeroext %_a)
|
||||
// aarch64-apple: void @c_arg_u8(i8 zeroext %_a)
|
||||
// aarch64-windows: void @c_arg_u8(i8 %_a)
|
||||
// aarch64-linux: void @c_arg_u8(i8 %_a)
|
||||
// arm: void @c_arg_u8(i8 zeroext %_a)
|
||||
// riscv: void @c_arg_u8(i8 zeroext %_a)
|
||||
// ZERO/SIGN-EXTENDING TO 32 BITS NON-EXTENDING
|
||||
// ====================================== ===============================
|
||||
// x86_64: void @c_arg_u8(i8 noundef zeroext %_a)
|
||||
// i686: void @c_arg_u8(i8 noundef zeroext %_a)
|
||||
// aarch64-apple: void @c_arg_u8(i8 noundef zeroext %_a)
|
||||
// aarch64-windows: void @c_arg_u8(i8 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_u8(i8 noundef %_a)
|
||||
// arm: void @c_arg_u8(i8 noundef zeroext %_a)
|
||||
// riscv: void @c_arg_u8(i8 noundef zeroext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_u8(_a: u8) { }
|
||||
|
||||
// x86_64: void @c_arg_u16(i16 zeroext %_a)
|
||||
// i686: void @c_arg_u16(i16 zeroext %_a)
|
||||
// aarch64-apple: void @c_arg_u16(i16 zeroext %_a)
|
||||
// aarch64-windows: void @c_arg_u16(i16 %_a)
|
||||
// aarch64-linux: void @c_arg_u16(i16 %_a)
|
||||
// arm: void @c_arg_u16(i16 zeroext %_a)
|
||||
// riscv: void @c_arg_u16(i16 zeroext %_a)
|
||||
// x86_64: void @c_arg_u16(i16 noundef zeroext %_a)
|
||||
// i686: void @c_arg_u16(i16 noundef zeroext %_a)
|
||||
// aarch64-apple: void @c_arg_u16(i16 noundef zeroext %_a)
|
||||
// aarch64-windows: void @c_arg_u16(i16 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_u16(i16 noundef %_a)
|
||||
// arm: void @c_arg_u16(i16 noundef zeroext %_a)
|
||||
// riscv: void @c_arg_u16(i16 noundef zeroext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_u16(_a: u16) { }
|
||||
|
||||
// x86_64: void @c_arg_u32(i32 %_a)
|
||||
// i686: void @c_arg_u32(i32 %_a)
|
||||
// aarch64-apple: void @c_arg_u32(i32 %_a)
|
||||
// aarch64-windows: void @c_arg_u32(i32 %_a)
|
||||
// aarch64-linux: void @c_arg_u32(i32 %_a)
|
||||
// arm: void @c_arg_u32(i32 %_a)
|
||||
// riscv: void @c_arg_u32(i32 signext %_a)
|
||||
// x86_64: void @c_arg_u32(i32 noundef %_a)
|
||||
// i686: void @c_arg_u32(i32 noundef %_a)
|
||||
// aarch64-apple: void @c_arg_u32(i32 noundef %_a)
|
||||
// aarch64-windows: void @c_arg_u32(i32 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_u32(i32 noundef %_a)
|
||||
// arm: void @c_arg_u32(i32 noundef %_a)
|
||||
// riscv: void @c_arg_u32(i32 noundef signext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_u32(_a: u32) { }
|
||||
|
||||
// x86_64: void @c_arg_u64(i64 %_a)
|
||||
// i686: void @c_arg_u64(i64 %_a)
|
||||
// aarch64-apple: void @c_arg_u64(i64 %_a)
|
||||
// aarch64-windows: void @c_arg_u64(i64 %_a)
|
||||
// aarch64-linux: void @c_arg_u64(i64 %_a)
|
||||
// arm: void @c_arg_u64(i64 %_a)
|
||||
// riscv: void @c_arg_u64(i64 %_a)
|
||||
// x86_64: void @c_arg_u64(i64 noundef %_a)
|
||||
// i686: void @c_arg_u64(i64 noundef %_a)
|
||||
// aarch64-apple: void @c_arg_u64(i64 noundef %_a)
|
||||
// aarch64-windows: void @c_arg_u64(i64 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_u64(i64 noundef %_a)
|
||||
// arm: void @c_arg_u64(i64 noundef %_a)
|
||||
// riscv: void @c_arg_u64(i64 noundef %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_u64(_a: u64) { }
|
||||
|
||||
// x86_64: void @c_arg_i8(i8 signext %_a)
|
||||
// i686: void @c_arg_i8(i8 signext %_a)
|
||||
// aarch64-apple: void @c_arg_i8(i8 signext %_a)
|
||||
// aarch64-windows: void @c_arg_i8(i8 %_a)
|
||||
// aarch64-linux: void @c_arg_i8(i8 %_a)
|
||||
// arm: void @c_arg_i8(i8 signext %_a)
|
||||
// riscv: void @c_arg_i8(i8 signext %_a)
|
||||
// x86_64: void @c_arg_i8(i8 noundef signext %_a)
|
||||
// i686: void @c_arg_i8(i8 noundef signext %_a)
|
||||
// aarch64-apple: void @c_arg_i8(i8 noundef signext %_a)
|
||||
// aarch64-windows: void @c_arg_i8(i8 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_i8(i8 noundef %_a)
|
||||
// arm: void @c_arg_i8(i8 noundef signext %_a)
|
||||
// riscv: void @c_arg_i8(i8 noundef signext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_i8(_a: i8) { }
|
||||
|
||||
// x86_64: void @c_arg_i16(i16 signext %_a)
|
||||
// i686: void @c_arg_i16(i16 signext %_a)
|
||||
// aarch64-apple: void @c_arg_i16(i16 signext %_a)
|
||||
// aarch64-windows: void @c_arg_i16(i16 %_a)
|
||||
// aarch64-linux: void @c_arg_i16(i16 %_a)
|
||||
// arm: void @c_arg_i16(i16 signext %_a)
|
||||
// riscv: void @c_arg_i16(i16 signext %_a)
|
||||
// x86_64: void @c_arg_i16(i16 noundef signext %_a)
|
||||
// i686: void @c_arg_i16(i16 noundef signext %_a)
|
||||
// aarch64-apple: void @c_arg_i16(i16 noundef signext %_a)
|
||||
// aarch64-windows: void @c_arg_i16(i16 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_i16(i16 noundef %_a)
|
||||
// arm: void @c_arg_i16(i16 noundef signext %_a)
|
||||
// riscv: void @c_arg_i16(i16 noundef signext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_i16(_a: i16) { }
|
||||
|
||||
// x86_64: void @c_arg_i32(i32 %_a)
|
||||
// i686: void @c_arg_i32(i32 %_a)
|
||||
// aarch64-apple: void @c_arg_i32(i32 %_a)
|
||||
// aarch64-windows: void @c_arg_i32(i32 %_a)
|
||||
// aarch64-linux: void @c_arg_i32(i32 %_a)
|
||||
// arm: void @c_arg_i32(i32 %_a)
|
||||
// riscv: void @c_arg_i32(i32 signext %_a)
|
||||
// x86_64: void @c_arg_i32(i32 noundef %_a)
|
||||
// i686: void @c_arg_i32(i32 noundef %_a)
|
||||
// aarch64-apple: void @c_arg_i32(i32 noundef %_a)
|
||||
// aarch64-windows: void @c_arg_i32(i32 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_i32(i32 noundef %_a)
|
||||
// arm: void @c_arg_i32(i32 noundef %_a)
|
||||
// riscv: void @c_arg_i32(i32 noundef signext %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_i32(_a: i32) { }
|
||||
|
||||
// x86_64: void @c_arg_i64(i64 %_a)
|
||||
// i686: void @c_arg_i64(i64 %_a)
|
||||
// aarch64-apple: void @c_arg_i64(i64 %_a)
|
||||
// aarch64-windows: void @c_arg_i64(i64 %_a)
|
||||
// aarch64-linux: void @c_arg_i64(i64 %_a)
|
||||
// arm: void @c_arg_i64(i64 %_a)
|
||||
// riscv: void @c_arg_i64(i64 %_a)
|
||||
// x86_64: void @c_arg_i64(i64 noundef %_a)
|
||||
// i686: void @c_arg_i64(i64 noundef %_a)
|
||||
// aarch64-apple: void @c_arg_i64(i64 noundef %_a)
|
||||
// aarch64-windows: void @c_arg_i64(i64 noundef %_a)
|
||||
// aarch64-linux: void @c_arg_i64(i64 noundef %_a)
|
||||
// arm: void @c_arg_i64(i64 noundef %_a)
|
||||
// riscv: void @c_arg_i64(i64 noundef %_a)
|
||||
#[no_mangle] pub extern "C" fn c_arg_i64(_a: i64) { }
|
||||
|
||||
// x86_64: zeroext i8 @c_ret_u8()
|
||||
// i686: zeroext i8 @c_ret_u8()
|
||||
// aarch64-apple: zeroext i8 @c_ret_u8()
|
||||
// aarch64-windows: i8 @c_ret_u8()
|
||||
// aarch64-linux: i8 @c_ret_u8()
|
||||
// aarch64-windows: i8 @c_ret_u8()
|
||||
// aarch64-linux: i8 @c_ret_u8()
|
||||
// arm: zeroext i8 @c_ret_u8()
|
||||
// riscv: zeroext i8 @c_ret_u8()
|
||||
#[no_mangle] pub extern "C" fn c_ret_u8() -> u8 { 0 }
|
||||
@ -117,8 +117,8 @@
|
||||
// x86_64: zeroext i16 @c_ret_u16()
|
||||
// i686: zeroext i16 @c_ret_u16()
|
||||
// aarch64-apple: zeroext i16 @c_ret_u16()
|
||||
// aarch64-windows: i16 @c_ret_u16()
|
||||
// aarch64-linux: i16 @c_ret_u16()
|
||||
// aarch64-windows: i16 @c_ret_u16()
|
||||
// aarch64-linux: i16 @c_ret_u16()
|
||||
// arm: zeroext i16 @c_ret_u16()
|
||||
// riscv: zeroext i16 @c_ret_u16()
|
||||
#[no_mangle] pub extern "C" fn c_ret_u16() -> u16 { 0 }
|
||||
@ -126,8 +126,8 @@
|
||||
// x86_64: i32 @c_ret_u32()
|
||||
// i686: i32 @c_ret_u32()
|
||||
// aarch64-apple: i32 @c_ret_u32()
|
||||
// aarch64-windows: i32 @c_ret_u32()
|
||||
// aarch64-linux: i32 @c_ret_u32()
|
||||
// aarch64-windows: i32 @c_ret_u32()
|
||||
// aarch64-linux: i32 @c_ret_u32()
|
||||
// arm: i32 @c_ret_u32()
|
||||
// riscv: signext i32 @c_ret_u32()
|
||||
#[no_mangle] pub extern "C" fn c_ret_u32() -> u32 { 0 }
|
||||
@ -135,8 +135,8 @@
|
||||
// x86_64: i64 @c_ret_u64()
|
||||
// i686: i64 @c_ret_u64()
|
||||
// aarch64-apple: i64 @c_ret_u64()
|
||||
// aarch64-windows: i64 @c_ret_u64()
|
||||
// aarch64-linux: i64 @c_ret_u64()
|
||||
// aarch64-windows: i64 @c_ret_u64()
|
||||
// aarch64-linux: i64 @c_ret_u64()
|
||||
// arm: i64 @c_ret_u64()
|
||||
// riscv: i64 @c_ret_u64()
|
||||
#[no_mangle] pub extern "C" fn c_ret_u64() -> u64 { 0 }
|
||||
@ -144,8 +144,8 @@
|
||||
// x86_64: signext i8 @c_ret_i8()
|
||||
// i686: signext i8 @c_ret_i8()
|
||||
// aarch64-apple: signext i8 @c_ret_i8()
|
||||
// aarch64-windows: i8 @c_ret_i8()
|
||||
// aarch64-linux: i8 @c_ret_i8()
|
||||
// aarch64-windows: i8 @c_ret_i8()
|
||||
// aarch64-linux: i8 @c_ret_i8()
|
||||
// arm: signext i8 @c_ret_i8()
|
||||
// riscv: signext i8 @c_ret_i8()
|
||||
#[no_mangle] pub extern "C" fn c_ret_i8() -> i8 { 0 }
|
||||
@ -153,8 +153,8 @@
|
||||
// x86_64: signext i16 @c_ret_i16()
|
||||
// i686: signext i16 @c_ret_i16()
|
||||
// aarch64-apple: signext i16 @c_ret_i16()
|
||||
// aarch64-windows: i16 @c_ret_i16()
|
||||
// aarch64-linux: i16 @c_ret_i16()
|
||||
// aarch64-windows: i16 @c_ret_i16()
|
||||
// aarch64-linux: i16 @c_ret_i16()
|
||||
// arm: signext i16 @c_ret_i16()
|
||||
// riscv: signext i16 @c_ret_i16()
|
||||
#[no_mangle] pub extern "C" fn c_ret_i16() -> i16 { 0 }
|
||||
@ -162,8 +162,8 @@
|
||||
// x86_64: i32 @c_ret_i32()
|
||||
// i686: i32 @c_ret_i32()
|
||||
// aarch64-apple: i32 @c_ret_i32()
|
||||
// aarch64-windows: i32 @c_ret_i32()
|
||||
// aarch64-linux: i32 @c_ret_i32()
|
||||
// aarch64-windows: i32 @c_ret_i32()
|
||||
// aarch64-linux: i32 @c_ret_i32()
|
||||
// arm: i32 @c_ret_i32()
|
||||
// riscv: signext i32 @c_ret_i32()
|
||||
#[no_mangle] pub extern "C" fn c_ret_i32() -> i32 { 0 }
|
||||
@ -171,8 +171,8 @@
|
||||
// x86_64: i64 @c_ret_i64()
|
||||
// i686: i64 @c_ret_i64()
|
||||
// aarch64-apple: i64 @c_ret_i64()
|
||||
// aarch64-windows: i64 @c_ret_i64()
|
||||
// aarch64-linux: i64 @c_ret_i64()
|
||||
// aarch64-windows: i64 @c_ret_i64()
|
||||
// aarch64-linux: i64 @c_ret_i64()
|
||||
// arm: i64 @c_ret_i64()
|
||||
// riscv: i64 @c_ret_i64()
|
||||
#[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 }
|
||||
|
@ -5,7 +5,7 @@
|
||||
// FIXME(eddyb) all of these tests show memory stores and loads, even after a
|
||||
// scalar `bitcast`, more special-casing is required to remove `alloca` usage.
|
||||
|
||||
// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float %x)
|
||||
// CHECK-LABEL: define{{.*}}i32 @f32_to_bits(float noundef %x)
|
||||
// CHECK: store i32 %{{.*}}, {{.*}} %0
|
||||
// CHECK-NEXT: %[[RES:.*]] = load i32, {{.*}} %0
|
||||
// CHECK: ret i32 %[[RES]]
|
||||
@ -24,7 +24,7 @@ pub fn bool_to_byte(b: bool) -> u8 {
|
||||
unsafe { std::mem::transmute(b) }
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}}noundef zeroext i1 @byte_to_bool(i8 %byte)
|
||||
// CHECK-LABEL: define{{.*}}noundef zeroext i1 @byte_to_bool(i8 noundef %byte)
|
||||
// CHECK: %1 = trunc i8 %byte to i1
|
||||
// CHECK-NEXT: %2 = zext i1 %1 to i8
|
||||
// CHECK-NEXT: store i8 %2, {{.*}} %0
|
||||
@ -36,7 +36,7 @@ pub unsafe fn byte_to_bool(byte: u8) -> bool {
|
||||
std::mem::transmute(byte)
|
||||
}
|
||||
|
||||
// CHECK-LABEL: define{{.*}}{{i8\*|ptr}} @ptr_to_ptr({{i16\*|ptr}} %p)
|
||||
// CHECK-LABEL: define{{.*}}{{i8\*|ptr}} @ptr_to_ptr({{i16\*|ptr}} noundef %p)
|
||||
// CHECK: store {{i8\*|ptr}} %{{.*}}, {{.*}} %0
|
||||
// CHECK-NEXT: %[[RES:.*]] = load {{i8\*|ptr}}, {{.*}} %0
|
||||
// CHECK: ret {{i8\*|ptr}} %[[RES]]
|
||||
@ -52,7 +52,7 @@ pub fn ptr_to_ptr(p: *mut u16) -> *mut u8 {
|
||||
// Tests below show the non-special-cased behavior (with the possible
|
||||
// future special-cased instructions in the "NOTE(eddyb)" comments).
|
||||
|
||||
// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int({{i16\*|ptr}} %p)
|
||||
// CHECK: define{{.*}}[[USIZE:i[0-9]+]] @ptr_to_int({{i16\*|ptr}} noundef %p)
|
||||
|
||||
// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
|
||||
// %2 = ptrtoint i16* %p to [[USIZE]]
|
||||
@ -66,7 +66,7 @@ pub fn ptr_to_int(p: *mut u16) -> usize {
|
||||
unsafe { std::mem::transmute(p) }
|
||||
}
|
||||
|
||||
// CHECK: define{{.*}}{{i16\*|ptr}} @int_to_ptr([[USIZE]] %i)
|
||||
// CHECK: define{{.*}}{{i16\*|ptr}} @int_to_ptr([[USIZE]] noundef %i)
|
||||
|
||||
// NOTE(eddyb) see above, the following two CHECK lines should ideally be this:
|
||||
// %2 = inttoptr [[USIZE]] %i to i16*
|
||||
|
@ -6,31 +6,31 @@
|
||||
#![crate_type="lib"]
|
||||
|
||||
type ScalarZstLast = (u128, ());
|
||||
// CHECK: define i128 @test_ScalarZstLast(i128 %_1)
|
||||
// CHECK: define noundef i128 @test_ScalarZstLast(i128 noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarZstLast(_: ScalarZstLast) -> ScalarZstLast { loop {} }
|
||||
|
||||
type ScalarZstFirst = ((), u128);
|
||||
// CHECK: define i128 @test_ScalarZstFirst(i128 %_1)
|
||||
// CHECK: define noundef i128 @test_ScalarZstFirst(i128 noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarZstFirst(_: ScalarZstFirst) -> ScalarZstFirst { loop {} }
|
||||
|
||||
type ScalarPairZstLast = (u8, u128, ());
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairZstLast(i128 %_1.0, i8 %_1.1)
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairZstLast(i128 noundef %_1.0, i8 noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarPairZstLast(_: ScalarPairZstLast) -> ScalarPairZstLast { loop {} }
|
||||
|
||||
type ScalarPairZstFirst = ((), u8, u128);
|
||||
// CHECK: define { i8, i128 } @test_ScalarPairZstFirst(i8 %_1.0, i128 %_1.1)
|
||||
// CHECK: define { i8, i128 } @test_ScalarPairZstFirst(i8 noundef %_1.0, i128 noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarPairZstFirst(_: ScalarPairZstFirst) -> ScalarPairZstFirst { loop {} }
|
||||
|
||||
type ScalarPairLotsOfZsts = ((), u8, (), u128, ());
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairLotsOfZsts(i128 %_1.0, i8 %_1.1)
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairLotsOfZsts(i128 noundef %_1.0, i8 noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarPairLotsOfZsts(_: ScalarPairLotsOfZsts) -> ScalarPairLotsOfZsts { loop {} }
|
||||
|
||||
type ScalarPairLottaNesting = (((), ((), u8, (), u128, ())), ());
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairLottaNesting(i128 %_1.0, i8 %_1.1)
|
||||
// CHECK: define { i128, i8 } @test_ScalarPairLottaNesting(i128 noundef %_1.0, i8 noundef %_1.1)
|
||||
#[no_mangle]
|
||||
pub fn test_ScalarPairLottaNesting(_: ScalarPairLottaNesting) -> ScalarPairLottaNesting { loop {} }
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
// CHECK-LABEL: define{{.*}}i32 @test(i32 %a, i32 %b)
|
||||
// CHECK-LABEL: define{{.*}}i32 @test(i32 noundef %a, i32 noundef %b)
|
||||
#[no_mangle]
|
||||
pub fn test(a: u32, b: u32) -> u32 {
|
||||
let c = a + b;
|
||||
|
@ -4,7 +4,7 @@
|
||||
#![feature(repr_simd)]
|
||||
|
||||
// Hack to get the correct size for the length part in slices
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] %_1)
|
||||
// CHECK: @helper([[USIZE:i[0-9]+]] noundef %_1)
|
||||
#[no_mangle]
|
||||
pub fn helper(_: usize) {
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user