Move /src/test to /tests

This commit is contained in:
Albert Larsan 2023-01-05 09:13:28 +01:00
parent ca855e6e42
commit cf2dff2b1e
No known key found for this signature in database
GPG key ID: 92709B88BB8F13EA
27592 changed files with 0 additions and 0 deletions

View file

@ -1,4 +0,0 @@
# Compiler Test Documentation
Documentation for the compiler testing framework can be found in
[the rustc dev guide](https://rustc-dev-guide.rust-lang.org/tests/intro.html).

View file

@ -1,21 +0,0 @@
// compile-flags: -C no-prepopulate-passes -Zbranch-protection=bti
// assembly-output: emit-asm
// needs-asm-support
// only-aarch64
#![crate_type = "lib"]
#![feature(naked_functions)]
use std::arch::asm;
// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
// meaning "no prologue whatsoever, no, really, not one instruction."
// Unfortunately, aarch64's "branch target identification" works via hints at landing sites.
// LLVM implements this via making sure of that, even for functions with the naked attribute.
// So, we must emit an appropriate instruction instead!
#[no_mangle]
#[naked]
pub unsafe extern "C" fn _hlt() -> ! {
// CHECK-NOT: hint #34
// CHECK: hlt #0x1
asm!("hlt #1", options(noreturn))
}

View file

@ -1,21 +0,0 @@
// Test that PAC instructions are emitted when branch-protection is specified.
// assembly-output: emit-asm
// compile-flags: --target aarch64-unknown-linux-gnu
// compile-flags: -Z branch-protection=pac-ret,leaf
// needs-llvm-components: aarch64
#![feature(no_core, lang_items)]
#![no_std]
#![no_core]
#![crate_type = "lib"]
#[lang = "sized"]
trait Sized {}
// CHECK: hint #25
// CHECK: hint #29
#[no_mangle]
pub fn test() -> u8 {
42
}

View file

@ -1,48 +0,0 @@
// assembly-output: emit-asm
// compile-flags: -Copt-level=1
// only-x86_64
// min-llvm-version: 14.0
#![crate_type="rlib"]
// CHECK-LABEL: align_offset_byte_ptr
// CHECK: leaq 31
// CHECK: andq $-32
// CHECK: subq
#[no_mangle]
pub fn align_offset_byte_ptr(ptr: *const u8) -> usize {
ptr.align_offset(32)
}
// CHECK-LABEL: align_offset_byte_slice
// CHECK: leaq 31
// CHECK: andq $-32
// CHECK: subq
#[no_mangle]
pub fn align_offset_byte_slice(slice: &[u8]) -> usize {
slice.as_ptr().align_offset(32)
}
// CHECK-LABEL: align_offset_word_ptr
// CHECK: leaq 31
// CHECK: andq $-32
// CHECK: subq
// CHECK: shrq
// This `ptr` is not known to be aligned, so it is required to check if it is at all possible to
// align. LLVM applies a simple mask.
// CHECK: orq
#[no_mangle]
pub fn align_offset_word_ptr(ptr: *const u32) -> usize {
ptr.align_offset(32)
}
// CHECK-LABEL: align_offset_word_slice
// CHECK: leaq 31
// CHECK: andq $-32
// CHECK: subq
// CHECK: shrq
// `slice` is known to be aligned, so `!0` is not possible as a return
// CHECK-NOT: orq
#[no_mangle]
pub fn align_offset_word_slice(slice: &[u32]) -> usize {
slice.as_ptr().align_offset(32)
}

View file

@ -1,37 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target aarch64-unknown-linux-gnu
// needs-llvm-components: aarch64
#![feature(no_core, lang_items, rustc_attrs)]
#![crate_type = "rlib"]
#![no_core]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[lang = "sized"]
trait Sized {}
// CHECK-LABEL: ttbr0_el2:
#[no_mangle]
pub fn ttbr0_el2() {
// CHECK: //APP
// CHECK-NEXT: msr TTBR0_EL2, x0
// CHECK-NEXT: //NO_APP
unsafe {
asm!("msr ttbr0_el2, x0");
}
}
// CHECK-LABEL: vttbr_el2:
#[no_mangle]
pub fn vttbr_el2() {
// CHECK: //APP
// CHECK-NEXT: msr VTTBR_EL2, x0
// CHECK-NEXT: //NO_APP
unsafe {
asm!("msr vttbr_el2, x0");
}
}

View file

@ -1,145 +0,0 @@
// assembly-output: emit-asm
// compile-flags: -O
// compile-flags: --target aarch64-unknown-linux-gnu
// needs-llvm-components: aarch64
#![feature(no_core, lang_items, rustc_attrs)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for i32 {}
macro_rules! check {
($func:ident $reg:ident $code:literal) => {
// -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
#[no_mangle]
pub unsafe extern "C" fn $func() -> i32 {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!($code, out($reg) y);
y
}
};
}
// CHECK-LABEL: reg:
// CHECK: //APP
// CHECK: mov x0, x0
// CHECK: //NO_APP
check!(reg reg "mov {0}, {0}");
// CHECK-LABEL: reg_w:
// CHECK: //APP
// CHECK: mov w0, w0
// CHECK: //NO_APP
check!(reg_w reg "mov {0:w}, {0:w}");
// CHECK-LABEL: reg_x:
// CHECK: //APP
// CHECK: mov x0, x0
// CHECK: //NO_APP
check!(reg_x reg "mov {0:x}, {0:x}");
// CHECK-LABEL: vreg:
// CHECK: //APP
// CHECK: add v0.4s, v0.4s, v0.4s
// CHECK: //NO_APP
check!(vreg vreg "add {0}.4s, {0}.4s, {0}.4s");
// CHECK-LABEL: vreg_b:
// CHECK: //APP
// CHECK: ldr b0, [x0]
// CHECK: //NO_APP
check!(vreg_b vreg "ldr {:b}, [x0]");
// CHECK-LABEL: vreg_h:
// CHECK: //APP
// CHECK: ldr h0, [x0]
// CHECK: //NO_APP
check!(vreg_h vreg "ldr {:h}, [x0]");
// CHECK-LABEL: vreg_s:
// CHECK: //APP
// CHECK: ldr s0, [x0]
// CHECK: //NO_APP
check!(vreg_s vreg "ldr {:s}, [x0]");
// CHECK-LABEL: vreg_d:
// CHECK: //APP
// CHECK: ldr d0, [x0]
// CHECK: //NO_APP
check!(vreg_d vreg "ldr {:d}, [x0]");
// CHECK-LABEL: vreg_q:
// CHECK: //APP
// CHECK: ldr q0, [x0]
// CHECK: //NO_APP
check!(vreg_q vreg "ldr {:q}, [x0]");
// CHECK-LABEL: vreg_v:
// CHECK: //APP
// CHECK: add v0.4s, v0.4s, v0.4s
// CHECK: //NO_APP
check!(vreg_v vreg "add {0:v}.4s, {0:v}.4s, {0:v}.4s");
// CHECK-LABEL: vreg_low16:
// CHECK: //APP
// CHECK: add v0.4s, v0.4s, v0.4s
// CHECK: //NO_APP
check!(vreg_low16 vreg_low16 "add {0}.4s, {0}.4s, {0}.4s");
// CHECK-LABEL: vreg_low16_b:
// CHECK: //APP
// CHECK: ldr b0, [x0]
// CHECK: //NO_APP
check!(vreg_low16_b vreg_low16 "ldr {:b}, [x0]");
// CHECK-LABEL: vreg_low16_h:
// CHECK: //APP
// CHECK: ldr h0, [x0]
// CHECK: //NO_APP
check!(vreg_low16_h vreg_low16 "ldr {:h}, [x0]");
// CHECK-LABEL: vreg_low16_s:
// CHECK: //APP
// CHECK: ldr s0, [x0]
// CHECK: //NO_APP
check!(vreg_low16_s vreg_low16 "ldr {:s}, [x0]");
// CHECK-LABEL: vreg_low16_d:
// CHECK: //APP
// CHECK: ldr d0, [x0]
// CHECK: //NO_APP
check!(vreg_low16_d vreg_low16 "ldr {:d}, [x0]");
// CHECK-LABEL: vreg_low16_q:
// CHECK: //APP
// CHECK: ldr q0, [x0]
// CHECK: //NO_APP
check!(vreg_low16_q vreg_low16 "ldr {:q}, [x0]");
// CHECK-LABEL: vreg_low16_v:
// CHECK: //APP
// CHECK: add v0.4s, v0.4s, v0.4s
// CHECK: //NO_APP
check!(vreg_low16_v vreg_low16 "add {0:v}.4s, {0:v}.4s, {0:v}.4s");

View file

@ -1,16 +0,0 @@
// assembly-output: emit-asm
// compile-flags: -O
// compile-flags: --target aarch64-unknown-linux-gnu
// needs-llvm-components: aarch64
// only-aarch64
// only-linux
#![crate_type = "rlib"]
use std::sync::atomic::{AtomicI32, Ordering::*};
pub fn compare_exchange(a: &AtomicI32) {
// On AArch64 LLVM should outline atomic operations.
// CHECK: __aarch64_cas4_relax
let _ = a.compare_exchange(0, 10, Relaxed, Relaxed);
}

View file

@ -1,565 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target aarch64-unknown-linux-gnu
// needs-llvm-components: aarch64
#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *mut u8;
#[repr(simd)]
pub struct i8x8(i8, i8, i8, i8, i8, i8, i8, i8);
#[repr(simd)]
pub struct i16x4(i16, i16, i16, i16);
#[repr(simd)]
pub struct i32x2(i32, i32);
#[repr(simd)]
pub struct i64x1(i64);
#[repr(simd)]
pub struct f32x2(f32, f32);
#[repr(simd)]
pub struct f64x1(f64);
#[repr(simd)]
pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
#[repr(simd)]
pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
#[repr(simd)]
pub struct i32x4(i32, i32, i32, i32);
#[repr(simd)]
pub struct i64x2(i64, i64);
#[repr(simd)]
pub struct f32x4(f32, f32, f32, f32);
#[repr(simd)]
pub struct f64x2(f64, f64);
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for i64 {}
impl Copy for f64 {}
impl Copy for ptr {}
impl Copy for i8x8 {}
impl Copy for i16x4 {}
impl Copy for i32x2 {}
impl Copy for i64x1 {}
impl Copy for f32x2 {}
impl Copy for f64x1 {}
impl Copy for i8x16 {}
impl Copy for i16x8 {}
impl Copy for i32x4 {}
impl Copy for i64x2 {}
impl Copy for f32x4 {}
impl Copy for f64x2 {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// CHECK-LABEL: sym_fn:
// CHECK: //APP
// CHECK: bl extern_func
// CHECK: //NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("bl {}", sym extern_func);
}
// CHECK-LABEL: sym_static:
// CHECK: //APP
// CHECK: adr x0, extern_static
// CHECK: //NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
asm!("adr x0, {}", sym extern_static);
}
// Regression test for #75761
// CHECK-LABEL: issue_75761:
// CHECK: str {{.*}}x30
// CHECK: //APP
// CHECK: //NO_APP
// CHECK: ldr {{.*}}x30
#[no_mangle]
pub unsafe fn issue_75761() {
asm!("", out("v0") _, out("x30") _);
}
macro_rules! check {
($func:ident $ty:ident $class:ident $mov:literal $modifier:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(
concat!($mov, " {:", $modifier, "}, {:", $modifier, "}"),
out($class) y,
in($class) x
);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
// CHECK-LABEL: reg_i8:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_i8 i8 reg "mov" "");
// CHECK-LABEL: reg_i16:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_i16 i16 reg "mov" "");
// CHECK-LABEL: reg_i32:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_i32 i32 reg "mov" "");
// CHECK-LABEL: reg_f32:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_f32 f32 reg "mov" "");
// CHECK-LABEL: reg_i64:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_i64 i64 reg "mov" "");
// CHECK-LABEL: reg_f64:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_f64 f64 reg "mov" "");
// CHECK-LABEL: reg_ptr:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check!(reg_ptr ptr reg "mov" "");
// CHECK-LABEL: vreg_i8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i8 i8 vreg "fmov" "s");
// CHECK-LABEL: vreg_i16:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i16 i16 vreg "fmov" "s");
// CHECK-LABEL: vreg_i32:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i32 i32 vreg "fmov" "s");
// CHECK-LABEL: vreg_f32:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f32 f32 vreg "fmov" "s");
// CHECK-LABEL: vreg_i64:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i64 i64 vreg "fmov" "s");
// CHECK-LABEL: vreg_f64:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f64 f64 vreg "fmov" "s");
// CHECK-LABEL: vreg_ptr:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_ptr ptr vreg "fmov" "s");
// CHECK-LABEL: vreg_i8x8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i8x8 i8x8 vreg "fmov" "s");
// CHECK-LABEL: vreg_i16x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i16x4 i16x4 vreg "fmov" "s");
// CHECK-LABEL: vreg_i32x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i32x2 i32x2 vreg "fmov" "s");
// CHECK-LABEL: vreg_i64x1:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i64x1 i64x1 vreg "fmov" "s");
// CHECK-LABEL: vreg_f32x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f32x2 f32x2 vreg "fmov" "s");
// CHECK-LABEL: vreg_f64x1:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f64x1 f64x1 vreg "fmov" "s");
// CHECK-LABEL: vreg_i8x16:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i8x16 i8x16 vreg "fmov" "s");
// CHECK-LABEL: vreg_i16x8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i16x8 i16x8 vreg "fmov" "s");
// CHECK-LABEL: vreg_i32x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i32x4 i32x4 vreg "fmov" "s");
// CHECK-LABEL: vreg_i64x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_i64x2 i64x2 vreg "fmov" "s");
// CHECK-LABEL: vreg_f32x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f32x4 f32x4 vreg "fmov" "s");
// CHECK-LABEL: vreg_f64x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_f64x2 f64x2 vreg "fmov" "s");
// CHECK-LABEL: vreg_low16_i8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i8 i8 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i16:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i16 i16 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f32:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f32 f32 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i64:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i64 i64 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f64:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f64 f64 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_ptr:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_ptr ptr vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i8x8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i8x8 i8x8 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i16x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i16x4 i16x4 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i32x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i32x2 i32x2 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i64x1:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i64x1 i64x1 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f32x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f32x2 f32x2 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f64x1:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f64x1 f64x1 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i8x16:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i8x16 i8x16 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i16x8:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i16x8 i16x8 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i32x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i32x4 i32x4 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_i64x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_i64x2 i64x2 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f32x4:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f32x4 f32x4 vreg_low16 "fmov" "s");
// CHECK-LABEL: vreg_low16_f64x2:
// CHECK: //APP
// CHECK: fmov s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: //NO_APP
check!(vreg_low16_f64x2 f64x2 vreg_low16 "fmov" "s");
// CHECK-LABEL: x0_i8:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_i8 i8 "x0" "mov");
// CHECK-LABEL: x0_i16:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_i16 i16 "x0" "mov");
// CHECK-LABEL: x0_i32:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_i32 i32 "x0" "mov");
// CHECK-LABEL: x0_f32:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_f32 f32 "x0" "mov");
// CHECK-LABEL: x0_i64:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_i64 i64 "x0" "mov");
// CHECK-LABEL: x0_f64:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_f64 f64 "x0" "mov");
// CHECK-LABEL: x0_ptr:
// CHECK: //APP
// CHECK: mov x{{[0-9]+}}, x{{[0-9]+}}
// CHECK: //NO_APP
check_reg!(x0_ptr ptr "x0" "mov");
// CHECK-LABEL: v0_i8:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i8 i8 "s0" "fmov");
// CHECK-LABEL: v0_i16:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i16 i16 "s0" "fmov");
// CHECK-LABEL: v0_i32:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i32 i32 "s0" "fmov");
// CHECK-LABEL: v0_f32:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f32 f32 "s0" "fmov");
// CHECK-LABEL: v0_i64:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i64 i64 "s0" "fmov");
// CHECK-LABEL: v0_f64:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f64 f64 "s0" "fmov");
// CHECK-LABEL: v0_ptr:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_ptr ptr "s0" "fmov");
// CHECK-LABEL: v0_i8x8:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i8x8 i8x8 "s0" "fmov");
// CHECK-LABEL: v0_i16x4:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i16x4 i16x4 "s0" "fmov");
// CHECK-LABEL: v0_i32x2:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i32x2 i32x2 "s0" "fmov");
// CHECK-LABEL: v0_i64x1:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i64x1 i64x1 "s0" "fmov");
// CHECK-LABEL: v0_f32x2:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f32x2 f32x2 "s0" "fmov");
// CHECK-LABEL: v0_f64x1:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f64x1 f64x1 "s0" "fmov");
// CHECK-LABEL: v0_i8x16:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i8x16 i8x16 "s0" "fmov");
// CHECK-LABEL: v0_i16x8:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i16x8 i16x8 "s0" "fmov");
// CHECK-LABEL: v0_i32x4:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i32x4 i32x4 "s0" "fmov");
// CHECK-LABEL: v0_i64x2:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_i64x2 i64x2 "s0" "fmov");
// CHECK-LABEL: v0_f32x4:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f32x4 f32x4 "s0" "fmov");
// CHECK-LABEL: v0_f64x2:
// CHECK: //APP
// CHECK: fmov s0, s0
// CHECK: //NO_APP
check_reg!(v0_f64x2 f64x2 "s0" "fmov");

View file

@ -1,144 +0,0 @@
// assembly-output: emit-asm
// compile-flags: -O
// compile-flags: --target armv7-unknown-linux-gnueabihf
// compile-flags: -C target-feature=+neon
// needs-llvm-components: arm
#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[repr(simd)]
pub struct f32x4(f32, f32, f32, f32);
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for f32x4 {}
macro_rules! check {
($func:ident $modifier:literal $reg:ident $ty:ident $mov:literal) => {
// -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
#[no_mangle]
pub unsafe extern "C" fn $func() -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
y
}
};
}
// CHECK-LABEL: reg:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check!(reg "" reg i32 "mov");
// CHECK-LABEL: sreg:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check!(sreg "" sreg f32 "vmov.f32");
// CHECK-LABEL: sreg_low16:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check!(sreg_low16 "" sreg_low16 f32 "vmov.f32");
// CHECK-LABEL: dreg:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg "" dreg f64 "vmov.f64");
// CHECK-LABEL: dreg_low16:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg_low16 "" dreg_low16 f64 "vmov.f64");
// CHECK-LABEL: dreg_low8:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(dreg_low8 "" dreg_low8 f64 "vmov.f64");
// CHECK-LABEL: qreg:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg "" qreg f32x4 "vmov");
// CHECK-LABEL: qreg_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_e "e" qreg f32x4 "vmov.f64");
// CHECK-LABEL: qreg_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_f "f" qreg f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low8:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg_low8 "" qreg_low8 f32x4 "vmov");
// CHECK-LABEL: qreg_low8_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_low8_e "e" qreg_low8 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low8_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_low8_f "f" qreg_low8 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low4:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check!(qreg_low4 "" qreg_low4 f32x4 "vmov");
// CHECK-LABEL: qreg_low4_e:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check!(qreg_low4_e "e" qreg_low4 f32x4 "vmov.f64");
// CHECK-LABEL: qreg_low4_f:
// CHECK: @APP
// CHECK: vmov.f64 d1, d1
// CHECK: @NO_APP
check!(qreg_low4_f "f" qreg_low4 f32x4 "vmov.f64");

View file

@ -1,530 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target armv7-unknown-linux-gnueabihf
// compile-flags: -C target-feature=+neon
// needs-llvm-components: arm
#![feature(no_core, lang_items, rustc_attrs, repr_simd)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *mut u8;
#[repr(simd)]
pub struct i8x8(i8, i8, i8, i8, i8, i8, i8, i8);
#[repr(simd)]
pub struct i16x4(i16, i16, i16, i16);
#[repr(simd)]
pub struct i32x2(i32, i32);
#[repr(simd)]
pub struct i64x1(i64);
#[repr(simd)]
pub struct f32x2(f32, f32);
#[repr(simd)]
pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
#[repr(simd)]
pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
#[repr(simd)]
pub struct i32x4(i32, i32, i32, i32);
#[repr(simd)]
pub struct i64x2(i64, i64);
#[repr(simd)]
pub struct f32x4(f32, f32, f32, f32);
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for i64 {}
impl Copy for f64 {}
impl Copy for ptr {}
impl Copy for i8x8 {}
impl Copy for i16x4 {}
impl Copy for i32x2 {}
impl Copy for i64x1 {}
impl Copy for f32x2 {}
impl Copy for i8x16 {}
impl Copy for i16x8 {}
impl Copy for i32x4 {}
impl Copy for i64x2 {}
impl Copy for f32x4 {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// CHECK-LABEL: sym_fn:
// CHECK: @APP
// CHECK: bl extern_func
// CHECK: @NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("bl {}", sym extern_func);
}
// CHECK-LABEL: sym_static:
// CHECK: @APP
// CHECK: adr r0, extern_static
// CHECK: @NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
asm!("adr r0, {}", sym extern_static);
}
// Regression test for #82052.
// CHECK-LABEL: issue_82052
// CHECK: push {{.*}}lr
// CHECK: @APP
// CHECK: @NO_APP
pub unsafe fn issue_82052() {
asm!("", out("r14") _);
}
macro_rules! check {
($func:ident $ty:ident $class:ident $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
// CHECK-LABEL: reg_i8:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: @NO_APP
check!(reg_i8 i8 reg "mov");
// CHECK-LABEL: reg_i16:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: @NO_APP
check!(reg_i16 i16 reg "mov");
// CHECK-LABEL: reg_i32:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: @NO_APP
check!(reg_i32 i32 reg "mov");
// CHECK-LABEL: reg_f32:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: @NO_APP
check!(reg_f32 f32 reg "mov");
// CHECK-LABEL: reg_ptr:
// CHECK: @APP
// CHECK: mov {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: @NO_APP
check!(reg_ptr ptr reg "mov");
// CHECK-LABEL: sreg_i32:
// CHECK: @APP
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: @NO_APP
check!(sreg_i32 i32 sreg "vmov.f32");
// CHECK-LABEL: sreg_f32:
// CHECK: @APP
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: @NO_APP
check!(sreg_f32 f32 sreg "vmov.f32");
// CHECK-LABEL: sreg_ptr:
// CHECK: @APP
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: @NO_APP
check!(sreg_ptr ptr sreg "vmov.f32");
// CHECK-LABEL: sreg_low16_i32:
// CHECK: @APP
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: @NO_APP
check!(sreg_low16_i32 i32 sreg_low16 "vmov.f32");
// CHECK-LABEL: sreg_low16_f32:
// CHECK: @APP
// CHECK: vmov.f32 s{{[0-9]+}}, s{{[0-9]+}}
// CHECK: @NO_APP
check!(sreg_low16_f32 f32 sreg_low16 "vmov.f32");
// CHECK-LABEL: dreg_i64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_i64 i64 dreg "vmov.f64");
// CHECK-LABEL: dreg_f64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_f64 f64 dreg "vmov.f64");
// CHECK-LABEL: dreg_i8x8:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_i8x8 i8x8 dreg "vmov.f64");
// CHECK-LABEL: dreg_i16x4:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_i16x4 i16x4 dreg "vmov.f64");
// CHECK-LABEL: dreg_i32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_i32x2 i32x2 dreg "vmov.f64");
// CHECK-LABEL: dreg_i64x1:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_i64x1 i64x1 dreg "vmov.f64");
// CHECK-LABEL: dreg_f32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_f32x2 f32x2 dreg "vmov.f64");
// CHECK-LABEL: dreg_low16_i64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_i64 i64 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_f64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_f64 f64 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_i8x8:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_i8x8 i8x8 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_i16x4:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_i16x4 i16x4 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_i32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_i32x2 i32x2 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_i64x1:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_i64x1 i64x1 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low16_f32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low16_f32x2 f32x2 dreg_low16 "vmov.f64");
// CHECK-LABEL: dreg_low8_i64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_i64 i64 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_f64:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_f64 f64 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_i8x8:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_i8x8 i8x8 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_i16x4:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_i16x4 i16x4 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_i32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_i32x2 i32x2 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_i64x1:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_i64x1 i64x1 dreg_low8 "vmov.f64");
// CHECK-LABEL: dreg_low8_f32x2:
// CHECK: @APP
// CHECK: vmov.f64 d{{[0-9]+}}, d{{[0-9]+}}
// CHECK: @NO_APP
check!(dreg_low8_f32x2 f32x2 dreg_low8 "vmov.f64");
// CHECK-LABEL: qreg_i8x16:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_i8x16 i8x16 qreg "vmov");
// CHECK-LABEL: qreg_i16x8:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_i16x8 i16x8 qreg "vmov");
// CHECK-LABEL: qreg_i32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_i32x4 i32x4 qreg "vmov");
// CHECK-LABEL: qreg_i64x2:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_i64x2 i64x2 qreg "vmov");
// CHECK-LABEL: qreg_f32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_f32x4 f32x4 qreg "vmov");
// CHECK-LABEL: qreg_low8_i8x16:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low8_i8x16 i8x16 qreg_low8 "vmov");
// CHECK-LABEL: qreg_low8_i16x8:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low8_i16x8 i16x8 qreg_low8 "vmov");
// CHECK-LABEL: qreg_low8_i32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low8_i32x4 i32x4 qreg_low8 "vmov");
// CHECK-LABEL: qreg_low8_i64x2:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low8_i64x2 i64x2 qreg_low8 "vmov");
// CHECK-LABEL: qreg_low8_f32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low8_f32x4 f32x4 qreg_low8 "vmov");
// CHECK-LABEL: qreg_low4_i8x16:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_i8x16 i8x16 qreg_low4 "vmov");
// CHECK-LABEL: qreg_low4_i16x8:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_i16x8 i16x8 qreg_low4 "vmov");
// CHECK-LABEL: qreg_low4_i32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_i32x4 i32x4 qreg_low4 "vmov");
// CHECK-LABEL: qreg_low4_i64x2:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_i64x2 i64x2 qreg_low4 "vmov");
// CHECK-LABEL: qreg_low4_f32x4:
// CHECK: @APP
// CHECK: vorr q{{[0-9]+}}, q{{[0-9]+}}, q{{[0-9]+}}
// CHECK: @NO_APP
check!(qreg_low4_f32x4 f32x4 qreg_low4 "vmov");
// CHECK-LABEL: r0_i8:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check_reg!(r0_i8 i8 "r0" "mov");
// CHECK-LABEL: r0_i16:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check_reg!(r0_i16 i16 "r0" "mov");
// CHECK-LABEL: r0_i32:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check_reg!(r0_i32 i32 "r0" "mov");
// CHECK-LABEL: r0_f32:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check_reg!(r0_f32 f32 "r0" "mov");
// CHECK-LABEL: r0_ptr:
// CHECK: @APP
// CHECK: mov r0, r0
// CHECK: @NO_APP
check_reg!(r0_ptr ptr "r0" "mov");
// CHECK-LABEL: s0_i32:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check_reg!(s0_i32 i32 "s0" "vmov.f32");
// CHECK-LABEL: s0_f32:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check_reg!(s0_f32 f32 "s0" "vmov.f32");
// CHECK-LABEL: s0_ptr:
// CHECK: @APP
// CHECK: vmov.f32 s0, s0
// CHECK: @NO_APP
check_reg!(s0_ptr ptr "s0" "vmov.f32");
// CHECK-LABEL: d0_i64:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_i64 i64 "d0" "vmov.f64");
// CHECK-LABEL: d0_f64:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_f64 f64 "d0" "vmov.f64");
// CHECK-LABEL: d0_i8x8:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_i8x8 i8x8 "d0" "vmov.f64");
// CHECK-LABEL: d0_i16x4:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_i16x4 i16x4 "d0" "vmov.f64");
// CHECK-LABEL: d0_i32x2:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_i32x2 i32x2 "d0" "vmov.f64");
// CHECK-LABEL: d0_i64x1:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_i64x1 i64x1 "d0" "vmov.f64");
// CHECK-LABEL: d0_f32x2:
// CHECK: @APP
// CHECK: vmov.f64 d0, d0
// CHECK: @NO_APP
check_reg!(d0_f32x2 f32x2 "d0" "vmov.f64");
// CHECK-LABEL: q0_i8x16:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check_reg!(q0_i8x16 i8x16 "q0" "vmov");
// CHECK-LABEL: q0_i16x8:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check_reg!(q0_i16x8 i16x8 "q0" "vmov");
// CHECK-LABEL: q0_i32x4:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check_reg!(q0_i32x4 i32x4 "q0" "vmov");
// CHECK-LABEL: q0_i64x2:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check_reg!(q0_i64x2 i64x2 "q0" "vmov");
// CHECK-LABEL: q0_f32x4:
// CHECK: @APP
// CHECK: vorr q0, q0, q0
// CHECK: @NO_APP
check_reg!(q0_f32x4 f32x4 "q0" "vmov");

View file

@ -1,59 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target avr-unknown-gnu-atmega328
// needs-llvm-components: avr
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const u64;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for ptr {}
macro_rules! check {
($func:ident $hi:literal $lo:literal $reg:tt) => {
#[no_mangle]
unsafe fn $func() -> i16 {
let y;
asm!(concat!("mov {0:", $hi, "}, {0:", $lo, "}"), out($reg) y);
y
}
};
}
// CHECK-LABEL: reg_pair_modifiers:
// CHECK: ;APP
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
// CHECK: ;NO_APP
check!(reg_pair_modifiers "h" "l" reg_pair);
// CHECK-LABEL: reg_iw_modifiers:
// CHECK: ;APP
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
// CHECK: ;NO_APP
check!(reg_iw_modifiers "h" "l" reg_iw);
// CHECK-LABEL: reg_ptr_modifiers:
// CHECK: ;APP
// CHECK: mov r{{[1-9]?[13579]}}, r{{[1-9]?[24680]}}
// CHECK: ;NO_APP
check!(reg_ptr_modifiers "h" "l" reg_ptr);

View file

@ -1,221 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target avr-unknown-gnu-atmega328
// needs-llvm-components: avr
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const u64;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for ptr {}
macro_rules! check {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!("mov {}, {}", lateout($class) y, in($class) x);
y
}
};
}
macro_rules! checkw {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!("movw {}, {}", lateout($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!("mov ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
macro_rules! check_regw {
($func:ident $ty:ident $reg:tt $reg_lit:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!("movw ", $reg_lit, ", ", $reg_lit), lateout($reg) y, in($reg) x);
y
}
};
}
extern "C" {
fn extern_func();
static extern_static: i8;
}
// CHECK-LABEL: sym_fn
// CHECK: ;APP
// CHECK: call extern_func
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {}", sym extern_func);
}
// CHECK-LABEL: sym_static
// CHECK: ;APP
// CHECK: lds r{{[0-9]+}}, extern_static
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn sym_static() -> i8 {
let y;
asm!("lds {}, {}", lateout(reg) y, sym extern_static);
y
}
// CHECK-LABEL: ld_z:
// CHECK: ;APP
// CHECK: ld r{{[0-9]+}}, Z
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn ld_z(x: i16) -> i8 {
let y;
asm!("ld {}, Z", out(reg) y, in("Z") x);
y
}
// CHECK-LABEL: ldd_z:
// CHECK: ;APP
// CHECK: ldd r{{[0-9]+}}, Z+4
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn ldd_z(x: i16) -> i8 {
let y;
asm!("ldd {}, Z+4", out(reg) y, in("Z") x);
y
}
// CHECK-LABEL: ld_predecrement:
// CHECK: ;APP
// CHECK: ld r{{[0-9]+}}, -Z
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn ld_predecrement(x: i16) -> i8 {
let y;
asm!("ld {}, -Z", out(reg) y, in("Z") x);
y
}
// CHECK-LABEL: ld_postincrement:
// CHECK: ;APP
// CHECK: ld r{{[0-9]+}}, Z+
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn ld_postincrement(x: i16) -> i8 {
let y;
asm!("ld {}, Z+", out(reg) y, in("Z") x);
y
}
// CHECK-LABEL: muls_clobber:
// CHECK: ;APP
// CHECK: muls r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: movw r{{[0-9]+}}, r0
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn muls_clobber(x: i8, y: i8) -> i16 {
let z;
asm!(
"muls {}, {}",
"movw {}, r1:r0",
out(reg_iw) z,
in(reg) x,
in(reg) y,
);
z
}
// CHECK-LABEL: reg_i8:
// CHECK: ;APP
// CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
check!(reg_i8 i8 reg);
// CHECK-LABEL: reg_upper_i8:
// CHECK: ;APP
// CHECK: mov r{{[1-3][0-9]}}, r{{[1-3][0-9]}}
// CHECK: ;NO_APP
check!(reg_upper_i8 i8 reg_upper);
// CHECK-LABEL: reg_pair_i16:
// CHECK: ;APP
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
checkw!(reg_pair_i16 i16 reg_pair);
// CHECK-LABEL: reg_iw_i16:
// CHECK: ;APP
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
checkw!(reg_iw_i16 i16 reg_iw);
// CHECK-LABEL: reg_ptr_i16:
// CHECK: ;APP
// CHECK: movw r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
checkw!(reg_ptr_i16 i16 reg_ptr);
// CHECK-LABEL: r2_i8:
// CHECK: ;APP
// CHECK: mov r2, r2
// CHECK: ;NO_APP
check_reg!(r2_i8 i8 "r2");
// CHECK-LABEL: xl_i8:
// CHECK: ;APP
// CHECK: mov r26, r26
// CHECK: ;NO_APP
check_reg!(xl_i8 i8 "XL");
// CHECK-LABEL: xh_i8:
// CHECK: ;APP
// CHECK: mov r27, r27
// CHECK: ;NO_APP
check_reg!(xh_i8 i8 "XH");
// CHECK-LABEL: x_i16:
// CHECK: ;APP
// CHECK: movw r26, r26
// CHECK: ;NO_APP
check_regw!(x_i16 i16 "X" "X");
// CHECK-LABEL: r25r24_i16:
// CHECK: ;APP
// CHECK: movw r24, r24
// CHECK: ;NO_APP
check_regw!(r25r24_i16 i16 "r25r24" "r24");

View file

@ -1,153 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target bpfel-unknown-none -C target_feature=+alu32
// needs-llvm-components: bpf
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const u64;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for ptr {}
macro_rules! check {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!("{} = {}", out($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!($reg, " = ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
extern "C" {
fn extern_func();
}
// CHECK-LABEL: sym_fn
// CHECK: #APP
// CHECK: call extern_func
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {}", sym extern_func);
}
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8 i8 reg);
// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16 i16 reg);
// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32 i32 reg);
// CHECK-LABEL: reg_i64:
// CHECK: #APP
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i64 i64 reg);
// CHECK-LABEL: wreg_i8:
// CHECK: #APP
// CHECK: w{{[0-9]+}} = w{{[0-9]+}}
// CHECK: #NO_APP
check!(wreg_i8 i8 wreg);
// CHECK-LABEL: wreg_i16:
// CHECK: #APP
// CHECK: w{{[0-9]+}} = w{{[0-9]+}}
// CHECK: #NO_APP
check!(wreg_i16 i16 wreg);
// CHECK-LABEL: wreg_i32:
// CHECK: #APP
// CHECK: w{{[0-9]+}} = w{{[0-9]+}}
// CHECK: #NO_APP
check!(wreg_i32 i32 wreg);
// CHECK-LABEL: r0_i8:
// CHECK: #APP
// CHECK: r0 = r0
// CHECK: #NO_APP
check_reg!(r0_i8 i8 "r0");
// CHECK-LABEL: r0_i16:
// CHECK: #APP
// CHECK: r0 = r0
// CHECK: #NO_APP
check_reg!(r0_i16 i16 "r0");
// CHECK-LABEL: r0_i32:
// CHECK: #APP
// CHECK: r0 = r0
// CHECK: #NO_APP
check_reg!(r0_i32 i32 "r0");
// CHECK-LABEL: r0_i64:
// CHECK: #APP
// CHECK: r0 = r0
// CHECK: #NO_APP
check_reg!(r0_i64 i64 "r0");
// CHECK-LABEL: w0_i8:
// CHECK: #APP
// CHECK: w0 = w0
// CHECK: #NO_APP
check_reg!(w0_i8 i8 "w0");
// CHECK-LABEL: w0_i16:
// CHECK: #APP
// CHECK: w0 = w0
// CHECK: #NO_APP
check_reg!(w0_i16 i16 "w0");
// CHECK-LABEL: w0_i32:
// CHECK: #APP
// CHECK: w0 = w0
// CHECK: #NO_APP
check_reg!(w0_i32 i32 "w0");

View file

@ -1,33 +0,0 @@
// only-x86_64
// only-linux
// assembly-output: emit-asm
// compile-flags: -C llvm-args=--x86-asm-syntax=intel
// compile-flags: -C symbol-mangling-version=v0
#![feature(asm_const)]
#![crate_type = "rlib"]
use std::arch::global_asm;
#[no_mangle]
fn my_func() {}
#[no_mangle]
static MY_STATIC: i32 = 0;
// CHECK: mov eax, eax
global_asm!("mov eax, eax");
// CHECK: mov ebx, 5
global_asm!("mov ebx, {}", const 5);
// CHECK: mov ecx, 5
global_asm!("movl ${}, %ecx", const 5, options(att_syntax));
// CHECK: call my_func
global_asm!("call {}", sym my_func);
// CHECK: lea rax, [rip + MY_STATIC]
global_asm!("lea rax, [rip + {}]", sym MY_STATIC);
// CHECK: call _RNvCsiubXh4Yz005_10global_asm6foobar
global_asm!("call {}", sym foobar);
// CHECK: _RNvCsiubXh4Yz005_10global_asm6foobar:
fn foobar() {
loop {}
}

View file

@ -1,181 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target hexagon-unknown-linux-musl
// needs-llvm-components: hexagon
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const i32;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
macro_rules! check {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!("{} = {}", out($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($reg, " = ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
// CHECK-LABEL: sym_static:
// CHECK: InlineAsm Start
// CHECK: r0 = {{#+}}extern_static
// CHECK: InlineAsm End
#[no_mangle]
pub unsafe fn sym_static() {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
asm!("r0 = #{}", sym extern_static);
}
// CHECK-LABEL: sym_fn:
// CHECK: InlineAsm Start
// CHECK: r0 = {{#+}}extern_func
// CHECK: InlineAsm End
#[no_mangle]
pub unsafe fn sym_fn() {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
asm!("r0 = #{}", sym extern_func);
}
// This is a test for multi-instruction packets,
// which require the escaped braces.
//
// CHECK-LABEL: packet:
// CHECK: InlineAsm Start
// CHECK: {
// CHECK: r{{[0-9]+}} = r0
// CHECK: memw(r1{{(\+#0)?}}) = r{{[0-9]+}}
// CHECK: }
// CHECK: InlineAsm End
#[no_mangle]
pub unsafe fn packet() {
let val = 1024;
asm!("{{
{} = r0
memw(r1) = {}
}}", out(reg) _, in(reg) &val);
}
// CHECK-LABEL: reg_ptr:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_ptr ptr reg);
// CHECK-LABEL: reg_f32:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_f32 f32 reg);
// CHECK-LABEL: reg_i32:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_i32 i32 reg);
// CHECK-LABEL: reg_i8:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_i8 i8 reg);
// CHECK-LABEL: reg_i16:
// CHECK: InlineAsm Start
// CHECK: r{{[0-9]+}} = r{{[0-9]+}}
// CHECK: InlineAsm End
check!(reg_i16 i16 reg);
// CHECK-LABEL: r0_ptr:
// CHECK: InlineAsm Start
// CHECK: r0 = r0
// CHECK: InlineAsm End
check_reg!(r0_ptr ptr "r0");
// CHECK-LABEL: r0_f32:
// CHECK: InlineAsm Start
// CHECK: r0 = r0
// CHECK: InlineAsm End
check_reg!(r0_f32 f32 "r0");
// CHECK-LABEL: r0_i32:
// CHECK: InlineAsm Start
// CHECK: r0 = r0
// CHECK: InlineAsm End
check_reg!(r0_i32 i32 "r0");
// CHECK-LABEL: r0_i8:
// CHECK: InlineAsm Start
// CHECK: r0 = r0
// CHECK: InlineAsm End
check_reg!(r0_i8 i8 "r0");
// CHECK-LABEL: r0_i16:
// CHECK: InlineAsm Start
// CHECK: r0 = r0
// CHECK: InlineAsm End
check_reg!(r0_i16 i16 "r0");

View file

@ -1,237 +0,0 @@
// revisions: mips32 mips64
// assembly-output: emit-asm
//[mips32] compile-flags: --target mips-unknown-linux-gnu
//[mips32] needs-llvm-components: mips
//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
//[mips64] needs-llvm-components: mips
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const i32;
impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
y
}
};}
macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};}
// mips32-LABEL: sym_static_32:
// mips32: #APP
// mips32: lw $3, %got(extern_static)
// mips32: #NO_APP
#[cfg(mips32)]
#[no_mangle]
pub unsafe fn sym_static_32() {
asm!("lw $v1, {}", sym extern_static);
}
// mips32-LABEL: sym_fn_32:
// mips32: #APP
// mips32: lw $3, %got(extern_func)
// mips32: #NO_APP
#[cfg(mips32)]
#[no_mangle]
pub unsafe fn sym_fn_32() {
asm!("lw $v1, {}", sym extern_func);
}
// mips64-LABEL: sym_static_64:
// mips64: #APP
// mips64: ld $3, %got_disp(extern_static)
// mips64: #NO_APP
#[cfg(mips64)]
#[no_mangle]
pub unsafe fn sym_static_64() {
asm!("ld $v1, {}", sym extern_static);
}
// mips64-LABEL: sym_fn_64:
// mips64: #APP
// mips64: ld $3, %got_disp(extern_func)
// mips64: #NO_APP
#[cfg(mips64)]
#[no_mangle]
pub unsafe fn sym_fn_64() {
asm!("ld $v1, {}", sym extern_func);
}
// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: mov.s $f{{[0-9]+}}, $f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32, f32, freg, "mov.s");
// CHECK-LABEL: f0_f32:
// CHECK: #APP
// CHECK: mov.s $f0, $f0
// CHECK: #NO_APP
#[no_mangle]
check_reg!(f0_f32, f32, "$f0", "mov.s");
// CHECK-LABEL: reg_f32_64:
// CHECK: #APP
// CHECK: mov.d $f{{[0-9]+}}, $f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32_64, f32, freg, "mov.d");
// CHECK-LABEL: f0_f32_64:
// CHECK: #APP
// CHECK: mov.d $f0, $f0
// CHECK: #NO_APP
#[no_mangle]
check_reg!(f0_f32_64, f32, "$f0", "mov.d");
// CHECK-LABEL: reg_f64:
// CHECK: #APP
// CHECK: mov.d $f{{[0-9]+}}, $f{{[0-9]+}}
// CHECK: #NO_APP
#[no_mangle]
check!(reg_f64, f64, freg, "mov.d");
// CHECK-LABEL: f0_f64:
// CHECK: #APP
// CHECK: mov.d $f0, $f0
// CHECK: #NO_APP
#[no_mangle]
check_reg!(f0_f64, f64, "$f0", "mov.d");
// CHECK-LABEL: reg_ptr:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_ptr, ptr, reg, "move");
// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32, i32, reg, "move");
// CHECK-LABEL: reg_f32_soft:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32_soft, f32, reg, "move");
// mips64-LABEL: reg_f64_soft:
// mips64: #APP
// mips64: move ${{[0-9]+}}, ${{[0-9]+}}
// mips64: #NO_APP
#[cfg(mips64)]
check!(reg_f64_soft, f64, reg, "move");
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8, i8, reg, "move");
// CHECK-LABEL: reg_u8:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_u8, u8, reg, "move");
// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: move ${{[0-9]+}}, ${{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16, i16, reg, "move");
// mips64-LABEL: reg_i64:
// mips64: #APP
// mips64: move ${{[0-9]+}}, ${{[0-9]+}}
// mips64: #NO_APP
#[cfg(mips64)]
check!(reg_i64, i64, reg, "move");
// CHECK-LABEL: r8_ptr:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_ptr, ptr, "$8", "move");
// CHECK-LABEL: r8_i32:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_i32, i32, "$8", "move");
// CHECK-LABEL: r8_f32:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_f32, f32, "$8", "move");
// CHECK-LABEL: r8_i8:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_i8, i8, "$8", "move");
// CHECK-LABEL: r8_u8:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_u8, u8, "$8", "move");
// CHECK-LABEL: r8_i16:
// CHECK: #APP
// CHECK: move $8, $8
// CHECK: #NO_APP
check_reg!(r8_i16, i16, "$8", "move");

View file

@ -1,157 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target msp430-none-elf
// needs-llvm-components: msp430
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch, asm_const)]
#![crate_type = "rlib"]
#![no_core]
#![allow(non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const i16;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for ptr {}
macro_rules! check {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!("mov {}, {}", lateout($class) y, in($class) x);
y
}
};
}
macro_rules! checkb {
($func:ident $ty:ident $class:ident) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!("mov.b {}, {}", lateout($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!("mov ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
macro_rules! check_regb {
($func:ident $ty:ident $reg:tt) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!("mov.b ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
extern "C" {
fn extern_func();
static extern_static: i8;
}
// CHECK-LABEL: sym_fn
// CHECK: ;APP
// CHECK: call extern_func
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {}", sym extern_func);
}
// CHECK-LABEL: sym_static
// CHECK: ;APP
// CHECK: mov.b extern_static, r{{[0-9]+}}
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn sym_static() -> i8 {
let y;
asm!("mov.b {1}, {0}", lateout(reg) y, sym extern_static);
y
}
// CHECK-LABEL: add_const:
// CHECK: ;APP
// CHECK: add.b #5, r{{[0-9]+}}
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn add_const() -> i8 {
let y;
asm!("add.b #{number}, {}", out(reg) y, number = const 5);
y
}
// CHECK-LABEL: mov_postincrement:
// CHECK: ;APP
// CHECK: mov @r5+, r{{[0-9]+}}
// CHECK: ;NO_APP
#[no_mangle]
pub unsafe fn mov_postincrement(mut x: *const i16) -> (i16, *const i16) {
let y;
asm!("mov @r5+, {0}", out(reg) y, inlateout("r5") x);
(y, x)
}
// CHECK-LABEL: reg_i8:
// CHECK: ;APP
// CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
check!(reg_i8 i8 reg);
// CHECK-LABEL: reg_i16:
// CHECK: ;APP
// CHECK: mov r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
check!(reg_i16 i16 reg);
// CHECK-LABEL: reg_i8b:
// CHECK: ;APP
// CHECK: mov.b r{{[0-9]+}}, r{{[0-9]+}}
// CHECK: ;NO_APP
checkb!(reg_i8b i8 reg);
// CHECK-LABEL: r5_i8:
// CHECK: ;APP
// CHECK: mov r5, r5
// CHECK: ;NO_APP
check_reg!(r5_i8 i8 "r5");
// CHECK-LABEL: r5_i16:
// CHECK: ;APP
// CHECK: mov r5, r5
// CHECK: ;NO_APP
check_reg!(r5_i16 i16 "r5");
// CHECK-LABEL: r5_i8b:
// CHECK: ;APP
// CHECK: mov.b r5, r5
// CHECK: ;NO_APP
check_regb!(r5_i8b i8 "r5");

View file

@ -1,133 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target nvptx64-nvidia-cuda
// compile-flags: --crate-type cdylib
// needs-llvm-components: nvptx
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
#![no_core]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *mut u8;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for i64 {}
impl Copy for f64 {}
impl Copy for ptr {}
// NVPTX does not support static variables
#[no_mangle]
fn extern_func() {}
// CHECK-LABEL: .visible .func sym_fn()
// CHECK: // begin inline asm
// CHECK: call extern_func;
// CHECK: // end inline asm
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {};", sym extern_func);
}
macro_rules! check {
($func:ident $ty:ident $class:ident $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!($mov, " {}, {};"), out($class) y, in($class) x);
y
}
};
}
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg16_i8
// CHECK: // begin inline asm
// CHECK: mov.i16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg16_i8 i8 reg16 "mov.i16");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg16_i16
// CHECK: // begin inline asm
// CHECK: mov.i16 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg16_i16 i16 reg16 "mov.i16");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i8
// CHECK: // begin inline asm
// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg32_i8 i8 reg32 "mov.i32");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i16
// CHECK: // begin inline asm
// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg32_i16 i16 reg32 "mov.i32");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_i32
// CHECK: // begin inline asm
// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg32_i32 i32 reg32 "mov.i32");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg32_f32
// CHECK: // begin inline asm
// CHECK: mov.i32 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg32_f32 f32 reg32 "mov.i32");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i8
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_i8 i8 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i16
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_i16 i16 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_i32
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_i32 i32 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b32 func_retval0) reg64_f32
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_f32 f32 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_i64
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_i64 i64 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_f64
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_f64 f64 reg64 "mov.i64");
// CHECK-LABEL: .visible .func (.param .b64 func_retval0) reg64_ptr
// CHECK: // begin inline asm
// CHECK: mov.i64 %{{[a-z0-9]+}}, %{{[a-z0-9]+}};
// CHECK: // end inline asm
check!(reg64_ptr ptr reg64 "mov.i64");

View file

@ -1,207 +0,0 @@
// revisions: powerpc powerpc64
// assembly-output: emit-asm
//[powerpc] compile-flags: --target powerpc-unknown-linux-gnu
//[powerpc] needs-llvm-components: powerpc
//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
//[powerpc64] needs-llvm-components: powerpc
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const i32;
impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
y
}
};}
macro_rules! check_reg { ($func:ident, $ty:ty, $rego:tt, $regc:tt, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " ", $rego, ", ", $rego), lateout($regc) y, in($regc) x);
y
}
};}
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8, i8, reg, "mr");
// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16, i16, reg, "mr");
// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32, i32, reg, "mr");
// powerpc64-LABEL: reg_i64:
// powerpc64: #APP
// powerpc64: mr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(powerpc64)]
check!(reg_i64, i64, reg, "mr");
// CHECK-LABEL: reg_i8_nz:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8_nz, i8, reg_nonzero, "mr");
// CHECK-LABEL: reg_i16_nz:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16_nz, i16, reg_nonzero, "mr");
// CHECK-LABEL: reg_i32_nz:
// CHECK: #APP
// CHECK: mr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32_nz, i32, reg_nonzero, "mr");
// powerpc64-LABEL: reg_i64_nz:
// powerpc64: #APP
// powerpc64: mr {{[0-9]+}}, {{[0-9]+}}
// powerpc64: #NO_APP
#[cfg(powerpc64)]
check!(reg_i64_nz, i64, reg_nonzero, "mr");
// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: fmr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32, f32, freg, "fmr");
// CHECK-LABEL: reg_f64:
// CHECK: #APP
// CHECK: fmr {{[0-9]+}}, {{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f64, f64, freg, "fmr");
// CHECK-LABEL: reg_i8_r0:
// CHECK: #APP
// CHECK: mr 0, 0
// CHECK: #NO_APP
check_reg!(reg_i8_r0, i8, "0", "0", "mr");
// CHECK-LABEL: reg_i16_r0:
// CHECK: #APP
// CHECK: mr 0, 0
// CHECK: #NO_APP
check_reg!(reg_i16_r0, i16, "0", "0", "mr");
// CHECK-LABEL: reg_i32_r0:
// CHECK: #APP
// CHECK: mr 0, 0
// CHECK: #NO_APP
check_reg!(reg_i32_r0, i32, "0", "0", "mr");
// powerpc64-LABEL: reg_i64_r0:
// powerpc64: #APP
// powerpc64: mr 0, 0
// powerpc64: #NO_APP
#[cfg(powerpc64)]
check_reg!(reg_i64_r0, i64, "0", "0", "mr");
// CHECK-LABEL: reg_i8_r18:
// CHECK: #APP
// CHECK: mr 18, 18
// CHECK: #NO_APP
check_reg!(reg_i8_r18, i8, "18", "18", "mr");
// CHECK-LABEL: reg_i16_r18:
// CHECK: #APP
// CHECK: mr 18, 18
// CHECK: #NO_APP
check_reg!(reg_i16_r18, i16, "18", "18", "mr");
// CHECK-LABEL: reg_i32_r18:
// CHECK: #APP
// CHECK: mr 18, 18
// CHECK: #NO_APP
check_reg!(reg_i32_r18, i32, "18", "18", "mr");
// powerpc64-LABEL: reg_i64_r18:
// powerpc64: #APP
// powerpc64: mr 18, 18
// powerpc64: #NO_APP
#[cfg(powerpc64)]
check_reg!(reg_i64_r18, i64, "18", "18", "mr");
// CHECK-LABEL: reg_f32_f0:
// CHECK: #APP
// CHECK: fmr 0, 0
// CHECK: #NO_APP
check_reg!(reg_f32_f0, f32, "0", "f0", "fmr");
// CHECK-LABEL: reg_f64_f0:
// CHECK: #APP
// CHECK: fmr 0, 0
// CHECK: #NO_APP
check_reg!(reg_f64_f0, f64, "0", "f0", "fmr");
// CHECK-LABEL: reg_f32_f18:
// CHECK: #APP
// CHECK: fmr 18, 18
// CHECK: #NO_APP
check_reg!(reg_f32_f18, f32, "18", "f18", "fmr");
// CHECK-LABEL: reg_f64_f18:
// CHECK: #APP
// CHECK: fmr 18, 18
// CHECK: #NO_APP
check_reg!(reg_f64_f18, f64, "18", "f18", "fmr");

View file

@ -1,210 +0,0 @@
// revisions: riscv64 riscv32
// assembly-output: emit-asm
//[riscv64] compile-flags: --target riscv64imac-unknown-none-elf
//[riscv64] needs-llvm-components: riscv
//[riscv32] compile-flags: --target riscv32imac-unknown-none-elf
//[riscv32] needs-llvm-components: riscv
// compile-flags: -C target-feature=+d
#![feature(no_core, lang_items, rustc_attrs)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *mut u8;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for i64 {}
impl Copy for f64 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// CHECK-LABEL: sym_fn:
// CHECK: #APP
// CHECK: call extern_func
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {}", sym extern_func);
}
// CHECK-LABEL: sym_static:
// CHECK: #APP
// CHECK: auipc t0, %pcrel_hi(extern_static)
// CHECK: lb t0, %pcrel_lo(.Lpcrel_hi{{[0-9]+}})(t0)
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
asm!("lb t0, {}", sym extern_static);
}
macro_rules! check {
($func:ident $ty:ident $class:ident $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
y
}
};
}
macro_rules! check_reg {
($func:ident $ty:ident $reg:tt $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
y
}
};
}
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: #NO_APP
check!(reg_i8 i8 reg "mv");
// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: #NO_APP
check!(reg_i16 i16 reg "mv");
// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: #NO_APP
check!(reg_i32 i32 reg "mv");
// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: #NO_APP
check!(reg_f32 f32 reg "mv");
// riscv64-LABEL: reg_i64:
// riscv64: #APP
// riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// riscv64: #NO_APP
#[cfg(riscv64)]
check!(reg_i64 i64 reg "mv");
// riscv64-LABEL: reg_f64:
// riscv64: #APP
// riscv64: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// riscv64: #NO_APP
#[cfg(riscv64)]
check!(reg_f64 f64 reg "mv");
// CHECK-LABEL: reg_ptr:
// CHECK: #APP
// CHECK: mv {{[a-z0-9]+}}, {{[a-z0-9]+}}
// CHECK: #NO_APP
check!(reg_ptr ptr reg "mv");
// CHECK-LABEL: freg_f32:
// CHECK: #APP
// CHECK: fmv.s f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
// CHECK: #NO_APP
check!(freg_f32 f32 freg "fmv.s");
// CHECK-LABEL: freg_f64:
// CHECK: #APP
// CHECK: fmv.d f{{[a-z0-9]+}}, f{{[a-z0-9]+}}
// CHECK: #NO_APP
check!(freg_f64 f64 freg "fmv.d");
// CHECK-LABEL: a0_i8:
// CHECK: #APP
// CHECK: mv a0, a0
// CHECK: #NO_APP
check_reg!(a0_i8 i8 "a0" "mv");
// CHECK-LABEL: a0_i16:
// CHECK: #APP
// CHECK: mv a0, a0
// CHECK: #NO_APP
check_reg!(a0_i16 i16 "a0" "mv");
// CHECK-LABEL: a0_i32:
// CHECK: #APP
// CHECK: mv a0, a0
// CHECK: #NO_APP
check_reg!(a0_i32 i32 "a0" "mv");
// CHECK-LABEL: a0_f32:
// CHECK: #APP
// CHECK: mv a0, a0
// CHECK: #NO_APP
check_reg!(a0_f32 f32 "a0" "mv");
// riscv64-LABEL: a0_i64:
// riscv64: #APP
// riscv64: mv a0, a0
// riscv64: #NO_APP
#[cfg(riscv64)]
check_reg!(a0_i64 i64 "a0" "mv");
// riscv64-LABEL: a0_f64:
// riscv64: #APP
// riscv64: mv a0, a0
// riscv64: #NO_APP
#[cfg(riscv64)]
check_reg!(a0_f64 f64 "a0" "mv");
// CHECK-LABEL: a0_ptr:
// CHECK: #APP
// CHECK: mv a0, a0
// CHECK: #NO_APP
check_reg!(a0_ptr ptr "a0" "mv");
// CHECK-LABEL: fa0_f32:
// CHECK: #APP
// CHECK: fmv.s fa0, fa0
// CHECK: #NO_APP
check_reg!(fa0_f32 f32 "fa0" "fmv.s");
// CHECK-LABEL: fa0_f64:
// CHECK: #APP
// CHECK: fmv.d fa0, fa0
// CHECK: #NO_APP
check_reg!(fa0_f64 f64 "fa0" "fmv.d");

View file

@ -1,167 +0,0 @@
// revisions: s390x
// assembly-output: emit-asm
//[s390x] compile-flags: --target s390x-unknown-linux-gnu
//[s390x] needs-llvm-components: systemz
#![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register, non_camel_case_types)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *const i32;
impl Copy for i8 {}
impl Copy for u8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for i64 {}
impl Copy for f32 {}
impl Copy for f64 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
y
}
};}
macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " %", $reg, ", %", $reg), lateout($reg) y, in($reg) x);
y
}
};}
// CHECK-LABEL: sym_fn_32:
// CHECK: #APP
// CHECK: brasl %r14, extern_func
// CHECK: #NO_APP
#[cfg(s390x)]
#[no_mangle]
pub unsafe fn sym_fn_32() {
asm!("brasl %r14, {}", sym extern_func);
}
// CHECK-LABEL: sym_static:
// CHECK: #APP
// CHECK: brasl %r14, extern_static
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
asm!("brasl %r14, {}", sym extern_static);
}
// CHECK-LABEL: reg_i8:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i8, i8, reg, "lgr");
// CHECK-LABEL: reg_i16:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i16, i16, reg, "lgr");
// CHECK-LABEL: reg_i32:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i32, i32, reg, "lgr");
// CHECK-LABEL: reg_i64:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_i64, i64, reg, "lgr");
// CHECK-LABEL: reg_f32:
// CHECK: #APP
// CHECK: ler %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f32, f32, freg, "ler");
// CHECK-LABEL: reg_f64:
// CHECK: #APP
// CHECK: ldr %f{{[0-9]+}}, %f{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_f64, f64, freg, "ldr");
// CHECK-LABEL: reg_ptr:
// CHECK: #APP
// CHECK: lgr %r{{[0-9]+}}, %r{{[0-9]+}}
// CHECK: #NO_APP
check!(reg_ptr, ptr, reg, "lgr");
// CHECK-LABEL: r0_i8:
// CHECK: #APP
// CHECK: lr %r0, %r0
// CHECK: #NO_APP
check_reg!(r0_i8, i8, "r0", "lr");
// CHECK-LABEL: r0_i16:
// CHECK: #APP
// CHECK: lr %r0, %r0
// CHECK: #NO_APP
check_reg!(r0_i16, i16, "r0", "lr");
// CHECK-LABEL: r0_i32:
// CHECK: #APP
// CHECK: lr %r0, %r0
// CHECK: #NO_APP
check_reg!(r0_i32, i32, "r0", "lr");
// CHECK-LABEL: r0_i64:
// CHECK: #APP
// CHECK: lr %r0, %r0
// CHECK: #NO_APP
check_reg!(r0_i64, i64, "r0", "lr");
// CHECK-LABEL: f0_f32:
// CHECK: #APP
// CHECK: ler %f0, %f0
// CHECK: #NO_APP
check_reg!(f0_f32, f32, "f0", "ler");
// CHECK-LABEL: f0_f64:
// CHECK: #APP
// CHECK: ldr %f0, %f0
// CHECK: #NO_APP
check_reg!(f0_f64, f64, "f0", "ldr");

View file

@ -1,149 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --target wasm32-unknown-unknown
// compile-flags: --crate-type cdylib
// needs-llvm-components: webassembly
#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
#![no_core]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
type ptr = *mut u8;
impl Copy for i8 {}
impl Copy for i16 {}
impl Copy for i32 {}
impl Copy for f32 {}
impl Copy for i64 {}
impl Copy for f64 {}
impl Copy for ptr {}
extern "C" {
fn extern_func();
static extern_static: u8;
}
// CHECK-LABEL: sym_fn:
// CHECK: #APP
// CHECK: call extern_func
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_fn() {
asm!("call {}", sym extern_func);
}
// CHECK-LABEL: sym_static
// CHECK: #APP
// CHECK: i32.const 42
// CHECK: i32.store extern_static
// CHECK: #NO_APP
#[no_mangle]
pub unsafe fn sym_static() {
asm!("
i32.const 42
i32.store {}
", sym extern_static);
}
macro_rules! check {
($func:ident $ty:ident $instr:literal) => {
#[no_mangle]
pub unsafe fn $func(x: $ty) -> $ty {
let y;
asm!(concat!("local.get {}\n", $instr, "\nlocal.set {}"), in(local) x, out(local) y);
y
}
};
}
// CHECK-LABEL: i8_i32:
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i32.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i8_i32 i8 "i32.clz");
// CHECK-LABEL: i16_i32:
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i32.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i16_i32 i16 "i32.clz");
// CHECK-LABEL: i32_i32:
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i32.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i32_i32 i32 "i32.clz");
// CHECK-LABEL: i8_i64
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i64.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i8_i64 i8 "i64.clz");
// CHECK-LABEL: i16_i64
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i64.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i16_i64 i16 "i64.clz");
// CHECK-LABEL: i32_i64
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i64.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i32_i64 i32 "i64.clz");
// CHECK-LABEL: i64_i64
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i64.clz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i64_i64 i64 "i64.clz");
// CHECK-LABEL: f32_f32
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: f32.abs
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(f32_f32 f32 "f32.abs");
// CHECK-LABEL: f64_f64
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: f64.abs
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(f64_f64 f64 "f64.abs");
// CHECK-LABEL: i32_ptr
// CHECK: #APP
// CHECK: local.get {{[0-9]}}
// CHECK: i32.eqz
// CHECK: local.set {{[0-9]}}
// CHECK: #NO_APP
check!(i32_ptr ptr "i32.eqz");

View file

@ -1,205 +0,0 @@
// revisions: x86_64 i686
// assembly-output: emit-asm
// compile-flags: -O
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64] needs-llvm-components: x86
//[i686] compile-flags: --target i686-unknown-linux-gnu
//[i686] needs-llvm-components: x86
// compile-flags: -C llvm-args=--x86-asm-syntax=intel
// compile-flags: -C target-feature=+avx512bw
#![feature(no_core, lang_items, rustc_attrs)]
#![crate_type = "rlib"]
#![no_core]
#![allow(asm_sub_register)]
#[rustc_builtin_macro]
macro_rules! asm {
() => {};
}
#[rustc_builtin_macro]
macro_rules! concat {
() => {};
}
#[rustc_builtin_macro]
macro_rules! stringify {
() => {};
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for i32 {}
macro_rules! check {
($func:ident $modifier:literal $reg:ident $mov:literal) => {
// -O and extern "C" guarantee that the selected register is always ax/xmm0
#[no_mangle]
pub unsafe extern "C" fn $func() -> i32 {
// Hack to avoid function merging
extern "Rust" {
fn dont_merge(s: &str);
}
dont_merge(stringify!($func));
let y;
asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
y
}
};
}
// CHECK-LABEL: reg:
// CHECK: #APP
// x86_64: mov rax, rax
// i686: mov eax, eax
// CHECK: #NO_APP
check!(reg "" reg "mov");
// x86_64-LABEL: reg_l:
// x86_64: #APP
// x86_64: mov al, al
// x86_64: #NO_APP
#[cfg(x86_64)]
check!(reg_l "l" reg "mov");
// CHECK-LABEL: reg_x:
// CHECK: #APP
// CHECK: mov ax, ax
// CHECK: #NO_APP
check!(reg_x "x" reg "mov");
// CHECK-LABEL: reg_e:
// CHECK: #APP
// CHECK: mov eax, eax
// CHECK: #NO_APP
check!(reg_e "e" reg "mov");
// x86_64-LABEL: reg_r:
// x86_64: #APP
// x86_64: mov rax, rax
// x86_64: #NO_APP
#[cfg(x86_64)]
check!(reg_r "r" reg "mov");
// CHECK-LABEL: reg_abcd:
// CHECK: #APP
// x86_64: mov rax, rax
// i686: mov eax, eax
// CHECK: #NO_APP
check!(reg_abcd "" reg_abcd "mov");
// CHECK-LABEL: reg_abcd_l:
// CHECK: #APP
// CHECK: mov al, al
// CHECK: #NO_APP
check!(reg_abcd_l "l" reg_abcd "mov");
// CHECK-LABEL: reg_abcd_h:
// CHECK: #APP
// CHECK: mov ah, ah
// CHECK: #NO_APP
check!(reg_abcd_h "h" reg_abcd "mov");
// CHECK-LABEL: reg_abcd_x:
// CHECK: #APP
// CHECK: mov ax, ax
// CHECK: #NO_APP
check!(reg_abcd_x "x" reg_abcd "mov");
// CHECK-LABEL: reg_abcd_e:
// CHECK: #APP
// CHECK: mov eax, eax
// CHECK: #NO_APP
check!(reg_abcd_e "e" reg_abcd "mov");
// x86_64-LABEL: reg_abcd_r:
// x86_64: #APP
// x86_64: mov rax, rax
// x86_64: #NO_APP
#[cfg(x86_64)]
check!(reg_abcd_r "r" reg_abcd "mov");
// CHECK-LABEL: xmm_reg
// CHECK: #APP
// CHECK: movaps xmm0, xmm0
// CHECK: #NO_APP
check!(xmm_reg "" xmm_reg "movaps");
// CHECK-LABEL: xmm_reg_x
// CHECK: #APP
// CHECK: movaps xmm0, xmm0
// CHECK: #NO_APP
check!(xmm_reg_x "x" xmm_reg "movaps");
// CHECK-LABEL: xmm_reg_y
// CHECK: #APP
// CHECK: vmovaps ymm0, ymm0
// CHECK: #NO_APP
check!(xmm_reg_y "y" xmm_reg "vmovaps");
// CHECK-LABEL: xmm_reg_z
// CHECK: #APP
// CHECK: vmovaps zmm0, zmm0
// CHECK: #NO_APP
check!(xmm_reg_z "z" xmm_reg "vmovaps");
// CHECK-LABEL: ymm_reg
// CHECK: #APP
// CHECK: movaps ymm0, ymm0
// CHECK: #NO_APP
check!(ymm_reg "" ymm_reg "vmovaps");
// CHECK-LABEL: ymm_reg_x
// CHECK: #APP
// CHECK: movaps xmm0, xmm0
// CHECK: #NO_APP
check!(ymm_reg_x "x" ymm_reg "movaps");
// CHECK-LABEL: ymm_reg_y
// CHECK: #APP
// CHECK: vmovaps ymm0, ymm0
// CHECK: #NO_APP
check!(ymm_reg_y "y" ymm_reg "vmovaps");
// CHECK-LABEL: ymm_reg_z
// CHECK: #APP
// CHECK: vmovaps zmm0, zmm0
// CHECK: #NO_APP
check!(ymm_reg_z "z" ymm_reg "vmovaps");
// CHECK-LABEL: zmm_reg
// CHECK: #APP
// CHECK: movaps zmm0, zmm0
// CHECK: #NO_APP
check!(zmm_reg "" zmm_reg "vmovaps");
// CHECK-LABEL: zmm_reg_x
// CHECK: #APP
// CHECK: movaps xmm0, xmm0
// CHECK: #NO_APP
check!(zmm_reg_x "x" zmm_reg "movaps");
// CHECK-LABEL: zmm_reg_y
// CHECK: #APP
// CHECK: vmovaps ymm0, ymm0
// CHECK: #NO_APP
check!(zmm_reg_y "y" zmm_reg "vmovaps");
// CHECK-LABEL: zmm_reg_z
// CHECK: #APP
// CHECK: vmovaps zmm0, zmm0
// CHECK: #NO_APP
check!(zmm_reg_z "z" zmm_reg "vmovaps");
// Note: we don't have any way of ensuring that k1 is actually the register
// chosen by the register allocator, so this check may fail if a different
// register is chosen.
// CHECK-LABEL: kreg:
// CHECK: #APP
// CHECK: kmovb k1, k1
// CHECK: #NO_APP
check!(kreg "" kreg "kmovb");

File diff suppressed because it is too large Load diff

View file

@ -1,8 +0,0 @@
#![feature(core_intrinsics)]
#![no_std]
#[panic_handler]
unsafe fn breakpoint_panic_handler(_: &::core::panic::PanicInfo) -> ! {
core::intrinsics::breakpoint();
core::hint::unreachable_unchecked();
}

View file

@ -1,14 +0,0 @@
#![no_std]
#![deny(warnings)]
#[inline(never)]
#[no_mangle]
pub fn wrapping_external_fn(a: u32) -> u32 {
a.wrapping_mul(a)
}
#[inline(never)]
#[no_mangle]
pub fn panicking_external_fn(a: u32) -> u32 {
a * a
}

View file

@ -1,20 +0,0 @@
// Makes sure that `-Z dwarf-version=5` causes `rustc` to emit DWARF version 5.
// assembly-output: emit-asm
// compile-flags: -g --target x86_64-unknown-linux-gnu -Z dwarf-version=5
// needs-llvm-components: x86
#![feature(no_core, lang_items)]
#![crate_type = "rlib"]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
pub fn wibble() {}
// CHECK: .section .debug_info
// CHECK-NOT: .short 2
// CHECK-NOT: .short 4
// CHECK: .short 5

View file

@ -1,58 +0,0 @@
// assembly-output: emit-asm
// min-llvm-version: 14.0
// only-x86_64
// revisions: opt-speed opt-size
// [opt-speed] compile-flags: -Copt-level=1
// [opt-size] compile-flags: -Copt-level=s
#![crate_type="rlib"]
#![feature(core_intrinsics)]
#![feature(pointer_is_aligned)]
// CHECK-LABEL: is_aligned_to_unchecked
// CHECK: decq
// CHECK-NEXT: testq
// CHECK-NEXT: sete
// CHECK: retq
#[no_mangle]
pub unsafe fn is_aligned_to_unchecked(ptr: *const u8, align: usize) -> bool {
unsafe {
std::intrinsics::assume(align.is_power_of_two())
}
ptr.is_aligned_to(align)
}
// CHECK-LABEL: is_aligned_1
// CHECK: movb $1
// CHECK: retq
#[no_mangle]
pub fn is_aligned_1(ptr: *const u8) -> bool {
ptr.is_aligned()
}
// CHECK-LABEL: is_aligned_2
// CHECK: testb $1
// CHECK-NEXT: sete
// CHECK: retq
#[no_mangle]
pub fn is_aligned_2(ptr: *const u16) -> bool {
ptr.is_aligned()
}
// CHECK-LABEL: is_aligned_4
// CHECK: testb $3
// CHECK-NEXT: sete
// CHECK: retq
#[no_mangle]
pub fn is_aligned_4(ptr: *const u32) -> bool {
ptr.is_aligned()
}
// CHECK-LABEL: is_aligned_8
// CHECK: testb $7
// CHECK-NEXT: sete
// CHECK: retq
#[no_mangle]
pub fn is_aligned_8(ptr: *const u64) -> bool {
ptr.is_aligned()
}

View file

@ -1,25 +0,0 @@
// Check that niche selection prefers zero and that jumps are optimized away.
// See https://github.com/rust-lang/rust/pull/87794
// assembly-output: emit-asm
// only-x86
// compile-flags: -Copt-level=3
#![crate_type = "lib"]
#[repr(u8)]
pub enum Size {
One = 1,
Two = 2,
Three = 3,
}
#[no_mangle]
pub fn handle(x: Option<Size>) -> u8 {
match x {
None => 0,
Some(size) => size as u8,
}
}
// There should be no jumps in output
// CHECK-NOT: j

View file

@ -1,13 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib
// only-nvptx64
// ignore-nvptx64
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// Verify default target arch with ptx-linker.
// CHECK: .target sm_30
// CHECK: .address_size 64

View file

@ -1,10 +0,0 @@
// assembly-output: emit-asm
// compile-flags: --crate-type rlib
// only-nvptx64
// ignore-nvptx64
#![no_std]
// Verify default arch without ptx-linker involved.
// CHECK: .target sm_30
// CHECK: .address_size 64

View file

@ -1,13 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib -C link-arg=--arch=sm_60
// only-nvptx64
// ignore-nvptx64
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// Verify target arch override via `link-arg`.
// CHECK: .target sm_60
// CHECK: .address_size 64

View file

@ -1,13 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib -C target-cpu=sm_50
// only-nvptx64
// ignore-nvptx64
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// Verify target arch override via `target-cpu`.
// CHECK: .target sm_50
// CHECK: .address_size 64

View file

@ -1,86 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib
// only-nvptx64
// ignore-nvptx64
#![feature(abi_ptx, core_intrinsics)]
#![no_std]
use core::intrinsics::*;
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// Currently, LLVM NVPTX backend can only emit atomic instructions with
// `relaxed` (PTX default) ordering. But it's also useful to make sure
// the backend won't fail with other orders. Apparently, the backend
// doesn't support fences as well. As a workaround `llvm.nvvm.membar.*`
// could work, and perhaps on the long run, all the atomic operations
// should rather be provided by `core::arch::nvptx`.
// Also, PTX ISA doesn't have atomic `load`, `store` and `nand`.
// FIXME(denzp): add tests for `core::sync::atomic::*`.
#[no_mangle]
pub unsafe extern "ptx-kernel" fn atomics_kernel(a: *mut u32) {
// CHECK: atom.global.and.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.and.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_and(a, 1);
atomic_and_relaxed(a, 1);
// CHECK: atom.global.cas.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1, 2;
// CHECK: atom.global.cas.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1, 2;
atomic_cxchg(a, 1, 2);
atomic_cxchg_relaxed(a, 1, 2);
// CHECK: atom.global.max.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.max.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_max(a, 1);
atomic_max_relaxed(a, 1);
// CHECK: atom.global.min.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.min.s32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_min(a, 1);
atomic_min_relaxed(a, 1);
// CHECK: atom.global.or.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.or.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_or(a, 1);
atomic_or_relaxed(a, 1);
// CHECK: atom.global.max.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.max.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_umax(a, 1);
atomic_umax_relaxed(a, 1);
// CHECK: atom.global.min.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.min.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_umin(a, 1);
atomic_umin_relaxed(a, 1);
// CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_xadd(a, 1);
atomic_xadd_relaxed(a, 1);
// CHECK: atom.global.exch.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.exch.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_xchg(a, 1);
atomic_xchg_relaxed(a, 1);
// CHECK: atom.global.xor.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
// CHECK: atom.global.xor.b32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], 1;
atomic_xor(a, 1);
atomic_xor_relaxed(a, 1);
// CHECK: mov.u32 %[[sub_0_arg:r[0-9]+]], 100;
// CHECK: neg.s32 temp, %[[sub_0_arg]];
// CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], temp;
atomic_xsub(a, 100);
// CHECK: mov.u32 %[[sub_1_arg:r[0-9]+]], 200;
// CHECK: neg.s32 temp, %[[sub_1_arg]];
// CHECK: atom.global.add.u32 %{{r[0-9]+}}, [%{{rd[0-9]+}}], temp;
atomic_xsub_relaxed(a, 200);
}

View file

@ -1,27 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib
// only-nvptx64
// ignore-nvptx64
#![feature(abi_ptx)]
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// aux-build: non-inline-dependency.rs
extern crate non_inline_dependency as dep;
// Verify that no extra function declarations are present.
// CHECK-NOT: .func
// CHECK: .visible .entry top_kernel(
#[no_mangle]
pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
// CHECK: add.s32 %{{r[0-9]+}}, %{{r[0-9]+}}, 5;
*b = *a + 5;
}
// Verify that no extra function definitions are here.
// CHECK-NOT: .func
// CHECK-NOT: .entry

View file

@ -1,254 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib -C target-cpu=sm_86
// only-nvptx64
// ignore-nvptx64
// The following ABI tests are made with nvcc 11.6 does.
//
// The PTX ABI stability is tied to major versions of the PTX ISA
// These tests assume major version 7
//
//
// The following correspondence between types are assumed:
// u<N> - uint<N>_t
// i<N> - int<N>_t
// [T, N] - std::array<T, N>
// &T - T const*
// &mut T - T*
// CHECK: .version 7
#![feature(abi_ptx, lang_items, no_core)]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[repr(C)]
pub struct SingleU8 {
f: u8,
}
#[repr(C)]
pub struct DoubleU8 {
f: u8,
g: u8,
}
#[repr(C)]
pub struct TripleU8 {
f: u8,
g: u8,
h: u8,
}
#[repr(C)]
pub struct TripleU16 {
f: u16,
g: u16,
h: u16,
}
#[repr(C)]
pub struct TripleU32 {
f: u32,
g: u32,
h: u32,
}
#[repr(C)]
pub struct TripleU64 {
f: u64,
g: u64,
h: u64,
}
#[repr(C)]
pub struct DoubleFloat {
f: f32,
g: f32,
}
#[repr(C)]
pub struct TripleFloat {
f: f32,
g: f32,
h: f32,
}
#[repr(C)]
pub struct TripleDouble {
f: f64,
g: f64,
h: f64,
}
#[repr(C)]
pub struct ManyIntegers {
f: u8,
g: u16,
h: u32,
i: u64,
}
#[repr(C)]
pub struct ManyNumerics {
f: u8,
g: u16,
h: u32,
i: u64,
j: f32,
k: f64,
}
// CHECK: .visible .entry f_u8_arg(
// CHECK: .param .u8 f_u8_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u8_arg(_a: u8) {}
// CHECK: .visible .entry f_u16_arg(
// CHECK: .param .u16 f_u16_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u16_arg(_a: u16) {}
// CHECK: .visible .entry f_u32_arg(
// CHECK: .param .u32 f_u32_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u32_arg(_a: u32) {}
// CHECK: .visible .entry f_u64_arg(
// CHECK: .param .u64 f_u64_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u64_arg(_a: u64) {}
// CHECK: .visible .entry f_u128_arg(
// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u128_arg(_a: u128) {}
// CHECK: .visible .entry f_i8_arg(
// CHECK: .param .u8 f_i8_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_i8_arg(_a: i8) {}
// CHECK: .visible .entry f_i16_arg(
// CHECK: .param .u16 f_i16_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_i16_arg(_a: i16) {}
// CHECK: .visible .entry f_i32_arg(
// CHECK: .param .u32 f_i32_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_i32_arg(_a: i32) {}
// CHECK: .visible .entry f_i64_arg(
// CHECK: .param .u64 f_i64_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_i64_arg(_a: i64) {}
// CHECK: .visible .entry f_i128_arg(
// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_i128_arg(_a: i128) {}
// CHECK: .visible .entry f_f32_arg(
// CHECK: .param .f32 f_f32_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_f32_arg(_a: f32) {}
// CHECK: .visible .entry f_f64_arg(
// CHECK: .param .f64 f_f64_arg_param_0
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_f64_arg(_a: f64) {}
// CHECK: .visible .entry f_single_u8_arg(
// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_single_u8_arg(_a: SingleU8) {}
// CHECK: .visible .entry f_double_u8_arg(
// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_double_u8_arg(_a: DoubleU8) {}
// CHECK: .visible .entry f_triple_u8_arg(
// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_u8_arg(_a: TripleU8) {}
// CHECK: .visible .entry f_triple_u16_arg(
// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_u16_arg(_a: TripleU16) {}
// CHECK: .visible .entry f_triple_u32_arg(
// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_u32_arg(_a: TripleU32) {}
// CHECK: .visible .entry f_triple_u64_arg(
// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_u64_arg(_a: TripleU64) {}
// CHECK: .visible .entry f_many_integers_arg(
// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_many_integers_arg(_a: ManyIntegers) {}
// CHECK: .visible .entry f_double_float_arg(
// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_double_float_arg(_a: DoubleFloat) {}
// CHECK: .visible .entry f_triple_float_arg(
// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_float_arg(_a: TripleFloat) {}
// CHECK: .visible .entry f_triple_double_arg(
// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_triple_double_arg(_a: TripleDouble) {}
// CHECK: .visible .entry f_many_numerics_arg(
// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_many_numerics_arg(_a: ManyNumerics) {}
// CHECK: .visible .entry f_byte_array_arg(
// CHECK: .param .align 1 .b8 f_byte_array_arg_param_0[5]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_byte_array_arg(_a: [u8; 5]) {}
// CHECK: .visible .entry f_float_array_arg(
// CHECK: .param .align 4 .b8 f_float_array_arg_param_0[20]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_float_array_arg(_a: [f32; 5]) {}
// CHECK: .visible .entry f_u128_array_arg(
// CHECK: .param .align 16 .b8 f_u128_array_arg_param_0[80]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u128_array_arg(_a: [u128; 5]) {}
// CHECK: .visible .entry f_u32_slice_arg(
// CHECK: .param .u64 f_u32_slice_arg_param_0
// CHECK: .param .u64 f_u32_slice_arg_param_1
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_u32_slice_arg(_a: &[u32]) {}
// CHECK: .visible .entry f_tuple_u8_u8_arg(
// CHECK: .param .align 1 .b8 f_tuple_u8_u8_arg_param_0[2]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_arg(_a: (u8, u8)) {}
// CHECK: .visible .entry f_tuple_u32_u32_arg(
// CHECK: .param .align 4 .b8 f_tuple_u32_u32_arg_param_0[8]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_tuple_u32_u32_arg(_a: (u32, u32)) {}
// CHECK: .visible .entry f_tuple_u8_u8_u32_arg(
// CHECK: .param .align 4 .b8 f_tuple_u8_u8_u32_arg_param_0[8]
#[no_mangle]
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_u32_arg(_a: (u8, u8, u32)) {}

View file

@ -1,40 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type bin
// only-nvptx64
// ignore-nvptx64
#![feature(abi_ptx)]
#![no_main]
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// aux-build: non-inline-dependency.rs
extern crate non_inline_dependency as dep;
// Make sure declarations are there.
// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
// CHECK-LABEL: .visible .entry top_kernel(
#[no_mangle]
pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
// CHECK: call.uni (retval0),
// CHECK-NEXT: wrapping_external_fn
// CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0];
let lhs = dep::wrapping_external_fn(*a);
// CHECK: call.uni (retval0),
// CHECK-NEXT: panicking_external_fn
// CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0];
let rhs = dep::panicking_external_fn(*a);
// CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]];
// CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]];
*b = lhs + rhs;
}
// Verify that external function bodies are available.
// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
// CHECK: .func (.param .b32 func_retval0) panicking_external_fn

View file

@ -1,39 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib
// only-nvptx64
// ignore-nvptx64
#![feature(abi_ptx)]
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// aux-build: non-inline-dependency.rs
extern crate non_inline_dependency as dep;
// Make sure declarations are there.
// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
// CHECK: .func (.param .b32 func_retval0) panicking_external_fn
// CHECK-LABEL: .visible .entry top_kernel(
#[no_mangle]
pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
// CHECK: call.uni (retval0),
// CHECK-NEXT: wrapping_external_fn
// CHECK: ld.param.b32 %[[LHS:r[0-9]+]], [retval0+0];
let lhs = dep::wrapping_external_fn(*a);
// CHECK: call.uni (retval0),
// CHECK-NEXT: panicking_external_fn
// CHECK: ld.param.b32 %[[RHS:r[0-9]+]], [retval0+0];
let rhs = dep::panicking_external_fn(*a);
// CHECK: add.s32 %[[RES:r[0-9]+]], %[[RHS]], %[[LHS]];
// CHECK: st.global.u32 [%{{rd[0-9]+}}], %[[RES]];
*b = lhs + rhs;
}
// Verify that external function bodies are available.
// CHECK: .func (.param .b32 func_retval0) wrapping_external_fn
// CHECK: .func (.param .b32 func_retval0) panicking_external_fn

View file

@ -1,38 +0,0 @@
// assembly-output: ptx-linker
// compile-flags: --crate-type cdylib
// only-nvptx64
// ignore-nvptx64
#![feature(abi_ptx)]
#![no_std]
// aux-build: breakpoint-panic-handler.rs
extern crate breakpoint_panic_handler;
// Verify function name doesn't contain unacceaptable characters.
// CHECK: .func (.param .b32 func_retval0) [[IMPL_FN:[a-zA-Z0-9$_]+square[a-zA-Z0-9$_]+]](
// CHECK-LABEL: .visible .entry top_kernel(
#[no_mangle]
pub unsafe extern "ptx-kernel" fn top_kernel(a: *const u32, b: *mut u32) {
// CHECK: call.uni (retval0),
// CHECK-NEXT: [[IMPL_FN]]
*b = deep::private::MyStruct::new(*a).square();
}
pub mod deep {
pub mod private {
pub struct MyStruct<T>(T);
impl MyStruct<u32> {
pub fn new(a: u32) -> Self {
MyStruct(a)
}
#[inline(never)]
pub fn square(&self) -> u32 {
self.0.wrapping_mul(self.0)
}
}
}
}

View file

@ -1,8 +0,0 @@
// assembly-output: emit-asm
// only-x86_64-unknown-linux-gnu
// compile-flags: -C panic=unwind -C force-unwind-tables=n -O
#![crate_type = "lib"]
// CHECK-NOT: .cfi_startproc
pub fn foo() {}

View file

@ -1,12 +0,0 @@
// assembly-output: emit-asm
// only-x86_64-unknown-linux-gnu
// compile-flags: -C panic=unwind -C force-unwind-tables=n
#![crate_type = "lib"]
// CHECK-LABEL: foo:
// CHECK: .cfi_startproc
#[no_mangle]
fn foo() {
panic!();
}

View file

@ -1,35 +0,0 @@
// revisions: x64
// assembly-output: emit-asm
// [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pic
// [x64] needs-llvm-components: x86
#![feature(no_core, lang_items)]
#![no_core]
#![crate_type="rlib"]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
// CHECK-LABEL: call_other_fn:
// CHECK: {{(jmpq|callq)}} *other_fn@GOTPCREL(%rip)
#[no_mangle]
pub fn call_other_fn() -> u8 {
unsafe {
other_fn()
}
}
// CHECK-LABEL: other_fn:
// CHECK: callq *foreign_fn@GOTPCREL(%rip)
#[no_mangle]
#[inline(never)]
pub fn other_fn() -> u8 {
unsafe {
foreign_fn()
}
}
extern "C" {fn foreign_fn() -> u8;}

View file

@ -1,38 +0,0 @@
// revisions: x64
// assembly-output: emit-asm
// [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=pie
// [x64] needs-llvm-components: x86
#![feature(no_core, lang_items)]
#![no_core]
#![crate_type="rlib"]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
// CHECK-LABEL: call_other_fn:
// With PIE local functions are called "directly".
// CHECK: {{(jmp|callq)}} other_fn
#[no_mangle]
pub fn call_other_fn() -> u8 {
unsafe {
other_fn()
}
}
// CHECK-LABEL: other_fn:
// External functions are still called through GOT, since we don't know if the symbol
// is defined in the binary or in the shared library.
// CHECK: callq *foreign_fn@GOTPCREL(%rip)
#[no_mangle]
#[inline(never)]
pub fn other_fn() -> u8 {
unsafe {
foreign_fn()
}
}
extern "C" {fn foreign_fn() -> u8;}

View file

@ -1,70 +0,0 @@
// Test SPARC64 ABI
// - float structure members are passes in floating point registers
// (#86163)
// assembly-output: emit-asm
// needs-llvm-components: sparc
// compile-flags: --target=sparcv9-sun-solaris -Copt-level=3
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![no_core]
#[lang = "sized"]
pub trait Sized {}
#[lang = "copy"]
pub trait Copy {}
impl Copy for f32 {}
#[repr(C)]
pub struct Franta {
a: f32,
b: f32,
c: f32,
d: f32,
}
// NB: due to delay slots the `ld` following the call is actually executed before the call.
#[no_mangle]
pub unsafe extern "C" fn callee(arg: Franta) {
// CHECK-LABEL: callee:
// CHECK: st %f3, [[PLACE_D:.*]]
// CHECK: st %f2, [[PLACE_C:.*]]
// CHECK: st %f1, [[PLACE_B:.*]]
// CHECK: st %f0, [[PLACE_A:.*]]
// CHECK: call tst_use
// CHECK-NEXT: ld [[PLACE_A]], %f1
// CHECK: call tst_use
// CHECK-NEXT: ld [[PLACE_B]], %f1
// CHECK: call tst_use
// CHECK-NEXT: ld [[PLACE_C]], %f1
// CHECK: call tst_use
// CHECK-NEXT: ld [[PLACE_D]], %f1
clobber();
tst_use(arg.a);
tst_use(arg.b);
tst_use(arg.c);
tst_use(arg.d);
tail_call_avoidance_fn();
}
extern "C" {
fn opaque_callee(arg: Franta, intarg: i32);
fn tst_use(arg: f32);
fn clobber();
// This exists so that post-https://reviews.llvm.org/D138741 LLVM doesn't
// tail-call away some of our assertions.
fn tail_call_avoidance_fn();
}
#[no_mangle]
pub unsafe extern "C" fn caller() {
// CHECK-LABEL: caller:
// CHECK: ld [{{.*}}], %f0
// CHECK: ld [{{.*}}], %f1
// CHECK: ld [{{.*}}], %f2
// CHECK: ld [{{.*}}], %f3
// CHECK: call opaque_callee
// CHECK: mov 3, %o2
opaque_callee(Franta { a: 1.0, b: 2.0, c: 3.0, d: 4.0 }, 3);
tail_call_avoidance_fn();
}

View file

@ -1,396 +0,0 @@
// revisions: all strong basic none missing
// assembly-output: emit-asm
// ignore-macos slightly different policy on stack protection of arrays
// ignore-windows stack check code uses different function names
// ignore-nvptx64 stack protector is not supported
// [all] compile-flags: -Z stack-protector=all
// [strong] compile-flags: -Z stack-protector=strong
// [basic] compile-flags: -Z stack-protector=basic
// [none] compile-flags: -Z stack-protector=none
// compile-flags: -C opt-level=2 -Z merge-functions=disabled
#![crate_type = "lib"]
#![allow(incomplete_features)]
#![feature(unsized_locals, unsized_fn_params)]
// CHECK-LABEL: emptyfn:
#[no_mangle]
pub fn emptyfn() {
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: array_char
#[no_mangle]
pub fn array_char(f: fn(*const char)) {
let a = ['c'; 1];
let b = ['d'; 3];
let c = ['e'; 15];
f(&a as *const _);
f(&b as *const _);
f(&c as *const _);
// Any type of local array variable leads to stack protection with the
// "strong" heuristic. The 'basic' heuristic only adds stack protection to
// functions with local array variables of a byte-sized type, however. Since
// 'char' is 4 bytes in Rust, this function is not protected by the 'basic'
// heuristic
//
// (This test *also* takes the address of the local stack variables. We
// cannot know that this isn't what triggers the `strong` heuristic.
// However, the test strategy of passing the address of a stack array to an
// external function is sufficient to trigger the `basic` heuristic (see
// test `array_u8_large()`). Since the `basic` heuristic only checks for the
// presence of stack-local array variables, we can be confident that this
// test also captures this part of the `strong` heuristic specification.)
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: array_u8_1
#[no_mangle]
pub fn array_u8_1(f: fn(*const u8)) {
let a = [0u8; 1];
f(&a as *const _);
// The 'strong' heuristic adds stack protection to functions with local
// array variables regardless of their size.
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: array_u8_small:
#[no_mangle]
pub fn array_u8_small(f: fn(*const u8)) {
let a = [0u8; 2];
let b = [0u8; 7];
f(&a as *const _);
f(&b as *const _);
// Small arrays do not lead to stack protection by the 'basic' heuristic.
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: array_u8_large:
#[no_mangle]
pub fn array_u8_large(f: fn(*const u8)) {
let a = [0u8; 9];
f(&a as *const _);
// Since `a` is a byte array with size greater than 8, the basic heuristic
// will also protect this function.
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
#[derive(Copy, Clone)]
pub struct ByteSizedNewtype(u8);
// CHECK-LABEL: array_bytesizednewtype_9:
#[no_mangle]
pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
let a = [ByteSizedNewtype(0); 9];
f(&a as *const _);
// Since `a` is a byte array in the LLVM output, the basic heuristic will
// also protect this function.
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: local_var_addr_used_indirectly
#[no_mangle]
pub fn local_var_addr_used_indirectly(f: fn(bool)) {
let a = 5;
let a_addr = &a as *const _ as usize;
f(a_addr & 0x10 == 0);
// This function takes the address of a local variable taken. Although this
// address is never used as a way to refer to stack memory, the `strong`
// heuristic adds stack smash protection. This is also the case in C++:
// ```
// cat << EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk
// #include <cstdint>
// void f(void (*g)(bool)) {
// int32_t x;
// g((reinterpret_cast<uintptr_t>(&x) & 0x10U) == 0);
// }
// EOF
// ```
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: local_string_addr_taken
#[no_mangle]
pub fn local_string_addr_taken(f: fn(&String)) {
let x = String::new();
f(&x);
// Taking the address of the local variable `x` leads to stack smash
// protection with the `strong` heuristic, but not with the `basic`
// heuristic. It does not matter that the reference is not mut.
//
// An interesting note is that a similar function in C++ *would* be
// protected by the `basic` heuristic, because `std::string` has a char
// array internally as a small object optimization:
// ```
// cat <<EOF | clang++ -O2 -fstack-protector -S -x c++ - -o - | grep stack_chk
// #include <string>
// void f(void (*g)(const std::string&)) {
// std::string x;
// g(x);
// }
// EOF
// ```
//
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
pub trait SelfByRef {
fn f(&self) -> i32;
}
impl SelfByRef for i32 {
fn f(&self) -> i32 {
return self + 1;
}
}
// CHECK-LABEL: local_var_addr_taken_used_locally_only
#[no_mangle]
pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) {
let x = factory();
let g = x.f();
sink(g);
// Even though the local variable conceptually has its address taken, as
// it's passed by reference to the trait function, the use of the reference
// is easily inlined. There is therefore no stack smash protection even with
// the `strong` heuristic.
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
pub struct Gigastruct {
does: u64,
not: u64,
have: u64,
array: u64,
members: u64
}
// CHECK-LABEL: local_large_var_moved
#[no_mangle]
pub fn local_large_var_moved(f: fn(Gigastruct)) {
let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 };
f(x);
// Even though the local variable conceptually doesn't have its address
// taken, it's so large that the "move" is implemented with a reference to a
// stack-local variable in the ABI. Consequently, this function *is*
// protected by the `strong` heuristic. This is also the case for
// rvalue-references in C++, regardless of struct size:
// ```
// cat <<EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk
// #include <cstdint>
// #include <utility>
// void f(void (*g)(uint64_t&&)) {
// uint64_t x;
// g(std::move(x));
// }
// EOF
// ```
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: local_large_var_cloned
#[no_mangle]
pub fn local_large_var_cloned(f: fn(Gigastruct)) {
f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 });
// A new instance of `Gigastruct` is passed to `f()`, without any apparent
// connection to this stack frame. Still, since instances of `Gigastruct`
// are sufficiently large, it is allocated in the caller stack frame and
// passed as a pointer. As such, this function is *also* protected by the
// `strong` heuristic, just like `local_large_var_moved`. This is also the
// case for pass-by-value of sufficiently large structs in C++:
// ```
// cat <<EOF | clang++ -O2 -fstack-protector-strong -S -x c++ - -o - | grep stack_chk
// #include <cstdint>
// #include <utility>
// struct Gigastruct { uint64_t a, b, c, d, e; };
// void f(void (*g)(Gigastruct)) {
// g(Gigastruct{});
// }
// EOF
// ```
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
extern "C" {
// A call to an external `alloca` function is *not* recognized as an
// `alloca(3)` operation. This function is a compiler built-in, as the
// man page explains. Clang translates it to an LLVM `alloca`
// instruction with a count argument, which is also what the LLVM stack
// protector heuristics looks for. The man page for `alloca(3)` details
// a way to avoid using the compiler built-in: pass a -std=c11
// argument, *and* don't include <alloca.h>. Though this leads to an
// external alloca() function being called, it doesn't lead to stack
// protection being included. It even fails with a linker error
// "undefined reference to `alloca'". Example:
// ```
// cat<<EOF | clang -fstack-protector-strong -x c -std=c11 - -o /dev/null
// #include <stdlib.h>
// void * alloca(size_t);
// void f(void (*g)(void*)) {
// void * p = alloca(10);
// g(p);
// }
// int main() { return 0; }
// EOF
// ```
// The following tests demonstrate that calls to an external `alloca`
// function in Rust also doesn't trigger stack protection.
fn alloca(size: usize) -> *mut ();
}
// CHECK-LABEL: alloca_small_compile_time_constant_arg
#[no_mangle]
pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
f(unsafe { alloca(8) });
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: alloca_large_compile_time_constant_arg
#[no_mangle]
pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
f(unsafe { alloca(9) });
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: alloca_dynamic_arg
#[no_mangle]
pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
f(unsafe { alloca(n) });
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// The question then is: in what ways can Rust code generate array-`alloca`
// LLVM instructions? This appears to only be generated by
// rustc_codegen_ssa::traits::Builder::array_alloca() through
// rustc_codegen_ssa::mir::operand::OperandValue::store_unsized(). FWICT
// this is support for the "unsized locals" unstable feature:
// https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html.
// CHECK-LABEL: unsized_fn_param
#[no_mangle]
pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
let n = if l { 1 } else { 2 };
f(*Box::<[u8]>::from(&s[0..n])); // slice-copy with Box::from
// Even though slices are conceptually passed by-value both into this
// function and into `f()`, this is implemented with pass-by-reference
// using a suitably constructed fat-pointer (as if the functions
// accepted &[u8]). This function therefore doesn't need dynamic array
// alloca, and is therefore not protected by the `strong` or `basic`
// heuristics.
// all: __stack_chk_fail
// strong-NOT: __stack_chk_fail
// basic-NOT: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}
// CHECK-LABEL: unsized_local
#[no_mangle]
pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
let n = if l { 1 } else { 2 };
let mut a: [u8] = *Box::<[u8]>::from(&s[0..n]); // slice-copy with Box::from
f(&mut a);
// This function allocates a slice as a local variable in its stack
// frame. Since the size is not a compile-time constant, an array
// alloca is required, and the function is protected by both the
// `strong` and `basic` heuristic.
// all: __stack_chk_fail
// strong: __stack_chk_fail
// basic: __stack_chk_fail
// none-NOT: __stack_chk_fail
// missing-NOT: __stack_chk_fail
}

View file

@ -1,285 +0,0 @@
// Test that stack smash protection code is emitted for all tier1 and tier2
// targets, with the exception of nvptx64-nvidia-cuda
//
// revisions: r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 r21 r22 r23
// revisions: r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39 r40 r41 r42 r43 r44
// revisions: r45 r46 r47 r48 r49 r50 r51 r52 r53 r54 r55 r56 r57 r58 r59 r60 r61 r62 r63 r64 r65
// revisions: r66 r67 r68 r69 r70 r71 r72 r73 r74 r75 r76 r77 r78 r79 r80 r81 r82 r83 r84
// assembly-output: emit-asm
// [r1] compile-flags: --target aarch64-unknown-linux-gnu
// [r1] needs-llvm-components: aarch64
// [r2] compile-flags: --target i686-pc-windows-gnu
// [r2] needs-llvm-components: x86
// [r3] compile-flags: --target i686-pc-windows-msvc
// [r3] needs-llvm-components: x86
// [r4] compile-flags: --target i686-unknown-linux-gnu
// [r4] needs-llvm-components: x86
// [r5] compile-flags: --target x86_64-apple-darwin
// [r5] needs-llvm-components: x86
// [r6] compile-flags: --target x86_64-pc-windows-gnu
// [r6] needs-llvm-components: x86
// [r7] compile-flags: --target x86_64-pc-windows-msvc
// [r7] needs-llvm-components: x86
// [r8] compile-flags: --target x86_64-unknown-linux-gnu
// [r8] needs-llvm-components: x86
// [r9] compile-flags: --target aarch64-apple-darwin
// [r9] needs-llvm-components: aarch64
// [r10] compile-flags: --target aarch64-apple-ios
// [r10] needs-llvm-components: aarch64
// [r11] compile-flags: --target aarch64-unknown-fuchsia
// [r11] needs-llvm-components: aarch64
// [r12] compile-flags: --target aarch64-linux-android
// [r12] needs-llvm-components: aarch64
// [r13] compile-flags: --target aarch64-pc-windows-msvc
// [r13] needs-llvm-components: aarch64
// [r14] compile-flags: --target aarch64-unknown-linux-musl
// [r14] needs-llvm-components: aarch64
// [r15] compile-flags: --target aarch64-unknown-none
// [r15] needs-llvm-components: aarch64
// [r16] compile-flags: --target aarch64-unknown-none-softfloat
// [r16] needs-llvm-components: aarch64
// [r17] compile-flags: --target arm-linux-androideabi
// [r17] needs-llvm-components: arm
// [r18] compile-flags: --target arm-unknown-linux-gnueabi
// [r18] needs-llvm-components: arm
// [r19] compile-flags: --target arm-unknown-linux-gnueabihf
// [r19] needs-llvm-components: arm
// [r20] compile-flags: --target arm-unknown-linux-musleabi
// [r20] needs-llvm-components: arm
// [r21] compile-flags: --target arm-unknown-linux-musleabihf
// [r21] needs-llvm-components: arm
// [r22] compile-flags: --target armebv7r-none-eabi
// [r22] needs-llvm-components: arm
// [r23] compile-flags: --target armebv7r-none-eabihf
// [r23] needs-llvm-components: arm
// [r24] compile-flags: --target armv5te-unknown-linux-gnueabi
// [r24] needs-llvm-components: arm
// [r25] compile-flags: --target armv5te-unknown-linux-musleabi
// [r25] needs-llvm-components: arm
// [r26] compile-flags: --target armv7-linux-androideabi
// [r26] needs-llvm-components: arm
// [r27] compile-flags: --target armv7a-none-eabi
// [r27] needs-llvm-components: arm
// [r28] compile-flags: --target armv7r-none-eabi
// [r28] needs-llvm-components: arm
// [r29] compile-flags: --target armv7r-none-eabihf
// [r29] needs-llvm-components: arm
// [r30] compile-flags: --target armv7-unknown-linux-gnueabi
// [r30] needs-llvm-components: arm
// [r31] compile-flags: --target armv7-unknown-linux-gnueabihf
// [r31] needs-llvm-components: arm
// [r32] compile-flags: --target armv7-unknown-linux-musleabi
// [r32] needs-llvm-components: arm
// [r33] compile-flags: --target armv7-unknown-linux-musleabihf
// [r33] needs-llvm-components: arm
// [r34] compile-flags: --target asmjs-unknown-emscripten
// [r34] needs-llvm-components: webassembly
// [r35] compile-flags: --target i586-pc-windows-msvc
// [r35] needs-llvm-components: x86
// [r36] compile-flags: --target i586-unknown-linux-gnu
// [r36] needs-llvm-components: x86
// [r37] compile-flags: --target i586-unknown-linux-musl
// [r37] needs-llvm-components: x86
// [r38] compile-flags: --target i686-linux-android
// [r38] needs-llvm-components: x86
// [r39] compile-flags: --target i686-unknown-freebsd
// [r39] needs-llvm-components: x86
// [r40] compile-flags: --target i686-unknown-linux-musl
// [r40] needs-llvm-components: x86
// [r41] compile-flags: --target mips-unknown-linux-gnu
// [r41] needs-llvm-components: mips
// [r42] compile-flags: --target mips-unknown-linux-musl
// [r42] needs-llvm-components: mips
// [r43] compile-flags: --target mips64-unknown-linux-gnuabi64
// [r43] needs-llvm-components: mips
// [r44] compile-flags: --target mips64-unknown-linux-muslabi64
// [r44] needs-llvm-components: mips
// [r45] compile-flags: --target mips64el-unknown-linux-gnuabi64
// [r45] needs-llvm-components: mips
// [r46] compile-flags: --target mips64el-unknown-linux-muslabi64
// [r46] needs-llvm-components: mips
// [r47] compile-flags: --target mipsel-unknown-linux-gnu
// [r47] needs-llvm-components: mips
// [r48] compile-flags: --target mipsel-unknown-linux-musl
// [r48] needs-llvm-components: mips
// [r49] compile-flags: --target nvptx64-nvidia-cuda
// [r49] needs-llvm-components: nvptx
// [r50] compile-flags: --target powerpc-unknown-linux-gnu
// [r50] needs-llvm-components: powerpc
// [r51] compile-flags: --target powerpc64-unknown-linux-gnu
// [r51] needs-llvm-components: powerpc
// [r52] compile-flags: --target powerpc64le-unknown-linux-gnu
// [r52] needs-llvm-components: powerpc
// [r53] compile-flags: --target riscv32i-unknown-none-elf
// [r53] needs-llvm-components: riscv
// [r54] compile-flags: --target riscv32imac-unknown-none-elf
// [r54] needs-llvm-components: riscv
// [r55] compile-flags:--target riscv32imc-unknown-none-elf
// [r55] needs-llvm-components: riscv
// [r56] compile-flags:--target riscv64gc-unknown-linux-gnu
// [r56] needs-llvm-components: riscv
// [r57] compile-flags:--target riscv64gc-unknown-none-elf
// [r57] needs-llvm-components: riscv
// [r58] compile-flags:--target riscv64imac-unknown-none-elf
// [r58] needs-llvm-components: riscv
// [r59] compile-flags:--target s390x-unknown-linux-gnu
// [r59] needs-llvm-components: systemz
// [r60] compile-flags:--target sparc64-unknown-linux-gnu
// [r60] needs-llvm-components: sparc
// [r61] compile-flags:--target sparcv9-sun-solaris
// [r61] needs-llvm-components: sparc
// [r62] compile-flags:--target thumbv6m-none-eabi
// [r62] needs-llvm-components: arm
// [r63] compile-flags:--target thumbv7em-none-eabi
// [r63] needs-llvm-components: arm
// [r64] compile-flags:--target thumbv7em-none-eabihf
// [r64] needs-llvm-components: arm
// [r65] compile-flags:--target thumbv7m-none-eabi
// [r65] needs-llvm-components: arm
// [r66] compile-flags:--target thumbv7neon-linux-androideabi
// [r66] needs-llvm-components: arm
// [r67] compile-flags:--target thumbv7neon-unknown-linux-gnueabihf
// [r67] needs-llvm-components: arm
// [r68] compile-flags:--target thumbv8m.base-none-eabi
// [r68] needs-llvm-components: arm
// [r69] compile-flags:--target thumbv8m.main-none-eabi
// [r69] needs-llvm-components: arm
// [r70] compile-flags:--target thumbv8m.main-none-eabihf
// [r70] needs-llvm-components: arm
// [r71] compile-flags:--target wasm32-unknown-emscripten
// [r71] needs-llvm-components: webassembly
// [r72] compile-flags:--target wasm32-unknown-unknown
// [r72] needs-llvm-components: webassembly
// [r73] compile-flags:--target wasm32-wasi
// [r73] needs-llvm-components: webassembly
// [r74] compile-flags:--target x86_64-apple-ios
// [r74] needs-llvm-components: x86
// [r75] compile-flags:--target x86_64-fortanix-unknown-sgx
// [r75] needs-llvm-components: x86
// [r76] compile-flags:--target x86_64-unknown-fuchsia
// [r76] needs-llvm-components: x86
// [r77] compile-flags:--target x86_64-linux-android
// [r77] needs-llvm-components: x86
// [r78] compile-flags:--target x86_64-sun-solaris
// [r78] needs-llvm-components: x86
// [r79] compile-flags:--target x86_64-unknown-freebsd
// [r79] needs-llvm-components: x86
// [r80] compile-flags:--target x86_64-unknown-illumos
// [r80] needs-llvm-components: x86
// [r81] compile-flags:--target x86_64-unknown-linux-gnux32
// [r81] needs-llvm-components: x86
// [r82] compile-flags:--target x86_64-unknown-linux-musl
// [r82] needs-llvm-components: x86
// [r83] compile-flags:--target x86_64-unknown-netbsd
// [r83] needs-llvm-components: x86
// [r84] compile-flags: --target x86_64-unknown-redox
// [r84] needs-llvm-components: x86
// compile-flags: -Z stack-protector=all
// compile-flags: -C opt-level=2
#![crate_type = "lib"]
#![feature(no_core, lang_items)]
#![crate_type = "lib"]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[no_mangle]
pub fn foo() {
// CHECK: foo{{:|()}}
// MSVC does the stack checking within a stack-check function:
// r3: calll @__security_check_cookie
// r7: callq __security_check_cookie
// r13: bl __security_check_cookie
// r35: calll @__security_check_cookie
// cuda doesn't support stack-smash protection
// r49-NOT: __security_check_cookie
// r49-NOT: __stack_chk_fail
// Other targets do stack checking within the function, and call a failure function on error
// r1: __stack_chk_fail
// r2: __stack_chk_fail
// r4: __stack_chk_fail
// r5: __stack_chk_fail
// r6: __stack_chk_fail
// r8: __stack_chk_fail
// r9: __stack_chk_fail
// r10: __stack_chk_fail
// r11: __stack_chk_fail
// r12: __stack_chk_fail
// r14: __stack_chk_fail
// r15: __stack_chk_fail
// r16: __stack_chk_fail
// r17: __stack_chk_fail
// r18: __stack_chk_fail
// r19: __stack_chk_fail
// r20: __stack_chk_fail
// r21: __stack_chk_fail
// r22: __stack_chk_fail
// r23: __stack_chk_fail
// r24: __stack_chk_fail
// r25: __stack_chk_fail
// r26: __stack_chk_fail
// r27: __stack_chk_fail
// r28: __stack_chk_fail
// r29: __stack_chk_fail
// r30: __stack_chk_fail
// r31: __stack_chk_fail
// r32: __stack_chk_fail
// r33: __stack_chk_fail
// r34: __stack_chk_fail
// r36: __stack_chk_fail
// r37: __stack_chk_fail
// r38: __stack_chk_fail
// r39: __stack_chk_fail
// r40: __stack_chk_fail
// r41: __stack_chk_fail
// r42: __stack_chk_fail
// r43: __stack_chk_fail
// r44: __stack_chk_fail
// r45: __stack_chk_fail
// r46: __stack_chk_fail
// r47: __stack_chk_fail
// r48: __stack_chk_fail
// r50: __stack_chk_fail
// r51: __stack_chk_fail
// r52: __stack_chk_fail
// r53: __stack_chk_fail
// r54: __stack_chk_fail
// r55: __stack_chk_fail
// r56: __stack_chk_fail
// r57: __stack_chk_fail
// r58: __stack_chk_fail
// r59: __stack_chk_fail
// r60: __stack_chk_fail
// r61: __stack_chk_fail
// r62: __stack_chk_fail
// r63: __stack_chk_fail
// r64: __stack_chk_fail
// r65: __stack_chk_fail
// r66: __stack_chk_fail
// r67: __stack_chk_fail
// r68: __stack_chk_fail
// r69: __stack_chk_fail
// r70: __stack_chk_fail
// r71: __stack_chk_fail
// r72: __stack_chk_fail
// r73: __stack_chk_fail
// r74: __stack_chk_fail
// r75: __stack_chk_fail
// r76: __stack_chk_fail
// r77: __stack_chk_fail
// r78: __stack_chk_fail
// r79: __stack_chk_fail
// r80: __stack_chk_fail
// r81: __stack_chk_fail
// r82: __stack_chk_fail
// r83: __stack_chk_fail
// r84: __stack_chk_fail
}

View file

@ -1,86 +0,0 @@
// revisions: x64 A64 ppc64le
// assembly-output: emit-asm
// [x64] compile-flags: --target x86_64-unknown-linux-gnu -Crelocation-model=static
// [x64] needs-llvm-components: x86
// [A64] compile-flags: --target aarch64-unknown-linux-gnu -Crelocation-model=static
// [A64] needs-llvm-components: aarch64
// [ppc64le] compile-flags: --target powerpc64le-unknown-linux-gnu -Crelocation-model=static
// [ppc64le] needs-llvm-components: powerpc
#![feature(no_core, lang_items)]
#![no_core]
#![crate_type="rlib"]
#[lang="sized"]
trait Sized {}
#[lang="copy"]
trait Copy {}
#[lang="sync"]
trait Sync {}
#[lang = "drop_in_place"]
fn drop_in_place<T>(_: *mut T) {}
impl Copy for u8 {}
impl Sync for u8 {}
#[no_mangle]
pub static PIERIS: u8 = 42;
extern "C" {
static EXOCHORDA: *mut u8;
fn chaenomeles();
}
// CHECK-LABEL: banana:
// On the next line LLVM 14 produces a `movb`, whereas LLVM 15+ produces a `movzbl`.
// x64: {{movb|movzbl}} chaenomeles{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}}
// A64: adrp [[REG:[a-z0-9]+]], chaenomeles
// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG]], :lo12:chaenomeles]
#[no_mangle]
pub fn banana() -> u8 {
unsafe {
*(chaenomeles as *mut u8)
}
}
// CHECK-LABEL: peach:
// x64: {{movb|movzbl}} banana{{(\(%[a-z0-9]+\))?}}, %{{[a-z0-9]+}}
// A64: adrp [[REG2:[a-z0-9]+]], banana
// A64-NEXT: ldrb {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:banana]
#[no_mangle]
pub fn peach() -> u8 {
unsafe {
*(banana as *mut u8)
}
}
// CHECK-LABEL: mango:
// x64: movq EXOCHORDA{{(\(%[a-z0-9]+\))?}}, %[[REG:[a-z0-9]+]]
// x64-NEXT: {{movb|movzbl}} (%[[REG]]), %{{[a-z0-9]+}}
// A64: adrp [[REG2:[a-z0-9]+]], EXOCHORDA
// A64-NEXT: ldr {{[a-z0-9]+}}, {{\[}}[[REG2]], :lo12:EXOCHORDA]
#[no_mangle]
pub fn mango() -> u8 {
unsafe {
*EXOCHORDA
}
}
// CHECK-LABEL: orange:
// x64: mov{{l|absq}} $PIERIS, %{{[a-z0-9]+}}
// A64: adrp [[REG2:[a-z0-9]+]], PIERIS
// A64-NEXT: add {{[a-z0-9]+}}, [[REG2]], :lo12:PIERIS
#[no_mangle]
pub fn orange() -> &'static u8 {
&PIERIS
}
// For ppc64 we need to make sure to generate TOC entries even with the static relocation model
// ppc64le: .tc chaenomeles[TC],chaenomeles
// ppc64le: .tc banana[TC],banana
// ppc64le: .tc EXOCHORDA[TC],EXOCHORDA
// ppc64le: .tc PIERIS[TC],PIERIS

View file

@ -1,37 +0,0 @@
// assembly-output: emit-asm
// compile-flags: -Copt-level=1
// only-x86_64
// min-llvm-version: 15.0
#![crate_type = "rlib"]
// CHECK-LABEL: old_style
// CHECK: movq %{{.*}}, %rax
// CHECK: orq $1, %rax
// CHECK: retq
#[no_mangle]
pub fn old_style(a: *mut u8) -> *mut u8 {
(a as usize | 1) as *mut u8
}
// CHECK-LABEL: cheri_compat
// CHECK: movq %{{.*}}, %rax
// CHECK: orq $1, %rax
// CHECK: retq
#[no_mangle]
pub fn cheri_compat(a: *mut u8) -> *mut u8 {
let old = a as usize;
let new = old | 1;
let diff = new.wrapping_sub(old);
a.wrapping_add(diff)
}
// CHECK-LABEL: definitely_not_a_null_pointer
// CHECK: movq %{{.*}}, %rax
// CHECK: orq $1, %rax
// CHECK: retq
#[no_mangle]
pub fn definitely_not_a_null_pointer(a: *mut u8) -> *mut u8 {
let old = a as usize;
let new = old | 1;
a.wrapping_sub(old).wrapping_add(new)
}

View file

@ -1,42 +0,0 @@
// assembly-output: emit-asm
// needs-llvm-components: x86
// revisions: TWOFLAGS SINGLEFLAG
// compile-flags: --target=x86_64-unknown-linux-gnu
// [TWOFLAGS] compile-flags: -C target-feature=+rdrnd -C target-feature=+rdseed
// [SINGLEFLAG] compile-flags: -C target-feature=+rdrnd,+rdseed
// Target features set via flags aren't necessarily reflected in the IR, so the only way to test
// them is to build code that requires the features to be enabled to work.
//
// In this particular test if `rdrnd,rdseed` somehow didn't make it to LLVM, the instruction
// selection should crash.
//
// > LLVM ERROR: Cannot select: 0x7f00f400c010: i32,i32,ch = X86ISD::RDSEED 0x7f00f400bfa8:2
// > In function: foo
//
// See also src/test/codegen/target-feature-overrides.rs
#![feature(no_core, lang_items, link_llvm_intrinsics, abi_unadjusted)]
#![crate_type = "lib"]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for u32 {}
// Use of these requires target features to be enabled
extern "unadjusted" {
#[link_name = "llvm.x86.rdrand.32"]
fn x86_rdrand32_step() -> (u32, i32);
#[link_name = "llvm.x86.rdseed.32"]
fn x86_rdseed32_step() -> (u32, i32);
}
#[no_mangle]
pub unsafe fn foo() -> (u32, u32) {
// CHECK-LABEL: foo:
// CHECK: rdrand
// CHECK: rdseed
(x86_rdrand32_step().0, x86_rdseed32_step().0)
}

View file

@ -1,42 +0,0 @@
// min-llvm-version: 16
// revisions: x86_64 i686
// assembly-output: emit-asm
//[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
//[x86_64] needs-llvm-components: x86
//[i686] compile-flags: --target i686-unknown-linux-gnu
//[i686] needs-llvm-components: x86
// compile-flags: -C llvm-args=-x86-asm-syntax=intel
#![feature(no_core, lang_items)]
#![crate_type = "lib"]
#![no_core]
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
impl Copy for u8 {}
// Check that inline-asm stack probes are generated correctly.
// To avoid making this test fragile to slight asm changes,
// we only check that the stack pointer is decremented by a page at a time,
// instead of matching the whole probe sequence.
// CHECK-LABEL: small_stack_probe:
#[no_mangle]
pub fn small_stack_probe(x: u8, f: fn(&mut [u8; 8192])) {
// CHECK-NOT: __rust_probestack
// x86_64: sub rsp, 4096
// i686: sub esp, 4096
f(&mut [x; 8192]);
}
// CHECK-LABEL: big_stack_probe:
#[no_mangle]
pub fn big_stack_probe(x: u8, f: fn(&[u8; 65536])) {
// CHECK-NOT: __rust_probestack
// x86_64: sub rsp, 4096
// i686: sub esp, 4096
f(&mut [x; 65536]);
}

View file

@ -1,25 +0,0 @@
// Floating-point clamp is designed to be implementable as max+min,
// so check to make sure that's what it's actually emitting.
// assembly-output: emit-asm
// compile-flags: --crate-type=lib -O -C llvm-args=-x86-asm-syntax=intel
// only-x86_64
// CHECK-LABEL: clamp_demo:
#[no_mangle]
pub fn clamp_demo(a: f32, x: f32, y: f32) -> f32 {
// CHECK: maxss
// CHECK: minss
a.clamp(x, y)
}
// CHECK-LABEL: clamp12_demo:
#[no_mangle]
pub fn clamp12_demo(a: f32) -> f32 {
// CHECK: movss xmm1
// CHECK-NEXT: maxss xmm1, xmm0
// CHECK-NEXT: movss xmm0
// CHECK-NEXT: minss xmm0, xmm1
// CHECK: ret
a.clamp(1.0, 2.0)
}

View file

@ -1,17 +0,0 @@
// Test LVI load hardening on SGX enclave code
// assembly-output: emit-asm
// compile-flags: --crate-type staticlib
// only-x86_64-fortanix-unknown-sgx
#[no_mangle]
pub extern fn plus_one(r: &mut u64) {
*r = *r + 1;
}
// CHECK: plus_one
// CHECK: lfence
// CHECK-NEXT: addq
// CHECK: popq [[REGISTER:%[a-z]+]]
// CHECK-NEXT: lfence
// CHECK-NEXT: jmpq *[[REGISTER]]

View file

@ -1,12 +0,0 @@
// Test LVI ret hardening on generic rust code
// assembly-output: emit-asm
// compile-flags: --crate-type staticlib
// only-x86_64-fortanix-unknown-sgx
#[no_mangle]
pub extern fn myret() {}
// CHECK: myret:
// CHECK: popq [[REGISTER:%[a-z]+]]
// CHECK-NEXT: lfence
// CHECK-NEXT: jmpq *[[REGISTER]]

View file

@ -1,43 +0,0 @@
// Test LVI load hardening on SGX inline assembly code
// assembly-output: emit-asm
// compile-flags: --crate-type staticlib
// only-x86_64-fortanix-unknown-sgx
use std::arch::asm;
#[no_mangle]
pub extern "C" fn get(ptr: *const u64) -> u64 {
let value: u64;
unsafe {
asm!(".start_inline_asm:",
"mov {}, [{}]",
".end_inline_asm:",
out(reg) value,
in(reg) ptr);
}
value
}
// CHECK: get
// CHECK: .start_inline_asm
// CHECK-NEXT: movq
// CHECK-NEXT: lfence
// CHECK-NEXT: .end_inline_asm
#[no_mangle]
pub extern "C" fn myret() {
unsafe {
asm!(
".start_myret_inline_asm:",
"ret",
".end_myret_inline_asm:",
);
}
}
// CHECK: myret
// CHECK: .start_myret_inline_asm
// CHECK-NEXT: shlq $0, (%rsp)
// CHECK-NEXT: lfence
// CHECK-NEXT: retq

View file

@ -1,24 +0,0 @@
// compile-flags: -C no-prepopulate-passes -Zcf-protection=full
// assembly-output: emit-asm
// needs-asm-support
// only-x86_64
#![crate_type = "lib"]
#![feature(naked_functions)]
use std::arch::asm;
// The problem at hand: Rust has adopted a fairly strict meaning for "naked functions",
// meaning "no prologue whatsoever, no, really, not one instruction."
// Unfortunately, x86's control-flow enforcement, specifically indirect branch protection,
// works by using an instruction for each possible landing site,
// and LLVM implements this via making sure of that.
#[no_mangle]
#[naked]
pub unsafe extern "sysv64" fn will_halt() -> ! {
// CHECK-NOT: endbr{{32|64}}
// CHECK: hlt
asm!("hlt", options(noreturn))
}
// what about aarch64?
// "branch-protection"=false

View file

@ -1,34 +0,0 @@
// Test that jump tables are (not) emitted when the `-Zno-jump-tables`
// flag is (not) set.
// revisions: unset set
// assembly-output: emit-asm
// compile-flags: -O
// [set] compile-flags: -Zno-jump-tables
// only-x86_64
#![crate_type = "lib"]
extern "C" {
fn bar1();
fn bar2();
fn bar3();
fn bar4();
fn bar5();
fn bar6();
}
// CHECK-LABEL: foo:
#[no_mangle]
pub unsafe fn foo(x: i32) {
// unset: LJTI0_0
// set-NOT: LJTI0_0
match x {
1 => bar1(),
2 => bar2(),
3 => bar3(),
4 => bar4(),
5 => bar5(),
_ => bar6(),
}
}

View file

@ -1,12 +0,0 @@
// only-x86_64
// assembly-output: emit-asm
// compile-flags: --crate-type staticlib -Ctarget-feature=+sse4.2
// CHECK-LABEL: banana
// CHECK: crc32
#[no_mangle]
pub unsafe fn banana(v: u8) -> u32 {
use std::arch::x86_64::*;
let out = !0u32;
_mm_crc32_u8(out, v)
}

View file

@ -1,429 +0,0 @@
// Helper functions used only in tests
#include <stdint.h>
#include <stdlib.h>
#include <assert.h>
#include <stdarg.h>
// These functions are used in the unit tests for C ABI calls.
uint32_t
rust_dbg_extern_identity_u32(uint32_t u) {
return u;
}
uint64_t
rust_dbg_extern_identity_u64(uint64_t u) {
return u;
}
double
rust_dbg_extern_identity_double(double u) {
return u;
}
char
rust_dbg_extern_identity_u8(char u) {
return u;
}
typedef void *(*dbg_callback)(void*);
void *
rust_dbg_call(dbg_callback cb, void *data) {
return cb(data);
}
void rust_dbg_do_nothing() { }
struct TwoU8s {
uint8_t one;
uint8_t two;
};
struct TwoU8s
rust_dbg_extern_return_TwoU8s() {
struct TwoU8s s;
s.one = 10;
s.two = 20;
return s;
}
struct TwoU8s
rust_dbg_extern_identity_TwoU8s(struct TwoU8s u) {
return u;
}
struct TwoU16s {
uint16_t one;
uint16_t two;
};
struct TwoU16s
rust_dbg_extern_return_TwoU16s() {
struct TwoU16s s;
s.one = 10;
s.two = 20;
return s;
}
struct TwoU16s
rust_dbg_extern_identity_TwoU16s(struct TwoU16s u) {
return u;
}
struct TwoU32s {
uint32_t one;
uint32_t two;
};
struct TwoU32s
rust_dbg_extern_return_TwoU32s() {
struct TwoU32s s;
s.one = 10;
s.two = 20;
return s;
}
struct TwoU32s
rust_dbg_extern_identity_TwoU32s(struct TwoU32s u) {
return u;
}
struct TwoU64s {
uint64_t one;
uint64_t two;
};
struct TwoU64s
rust_dbg_extern_return_TwoU64s() {
struct TwoU64s s;
s.one = 10;
s.two = 20;
return s;
}
struct TwoU64s
rust_dbg_extern_identity_TwoU64s(struct TwoU64s u) {
return u;
}
struct TwoDoubles {
double one;
double two;
};
struct TwoDoubles
rust_dbg_extern_identity_TwoDoubles(struct TwoDoubles u) {
return u;
}
struct ManyInts {
int8_t arg1;
int16_t arg2;
int32_t arg3;
int16_t arg4;
int8_t arg5;
struct TwoU8s arg6;
};
// MSVC doesn't allow empty structs or unions
#ifndef _MSC_VER
struct Empty {
};
void
rust_dbg_extern_empty_struct(struct ManyInts v1, struct Empty e, struct ManyInts v2) {
assert(v1.arg1 == v2.arg1 + 1);
assert(v1.arg2 == v2.arg2 + 1);
assert(v1.arg3 == v2.arg3 + 1);
assert(v1.arg4 == v2.arg4 + 1);
assert(v1.arg5 == v2.arg5 + 1);
assert(v1.arg6.one == v2.arg6.one + 1);
assert(v1.arg6.two == v2.arg6.two + 1);
}
#endif
intptr_t
rust_get_test_int() {
return 1;
}
char *
rust_get_null_ptr() {
return 0;
}
// Debug helpers strictly to verify ABI conformance.
struct quad {
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
};
struct floats {
double a;
uint8_t b;
double c;
};
struct char_char_double {
uint8_t a;
uint8_t b;
double c;
};
struct char_char_float {
uint8_t a;
uint8_t b;
float c;
};
struct quad
rust_dbg_abi_1(struct quad q) {
struct quad qq = { q.c + 1,
q.d - 1,
q.a + 1,
q.b - 1 };
return qq;
}
struct floats
rust_dbg_abi_2(struct floats f) {
struct floats ff = { f.c + 1.0,
0xff,
f.a - 1.0 };
return ff;
}
struct char_char_double
rust_dbg_abi_3(struct char_char_double a) {
struct char_char_double ccd = { a.a + 1,
a.b - 1,
a.c + 1.0 };
return ccd;
}
struct char_char_float
rust_dbg_abi_4(struct char_char_float a) {
struct char_char_float ccd = { a.a + 1,
a.b - 1,
a.c + 1.0 };
return ccd;
}
int
rust_dbg_static_mut = 3;
void
rust_dbg_static_mut_check_four() {
assert(rust_dbg_static_mut == 4);
}
struct S {
uint64_t x;
uint64_t y;
uint64_t z;
};
uint64_t get_x(struct S s) {
return s.x;
}
uint64_t get_y(struct S s) {
return s.y;
}
uint64_t get_z(struct S s) {
return s.z;
}
uint64_t get_c_many_params(void *a, void *b, void *c, void *d, struct quad f) {
return f.c;
}
struct quad_floats {
float a;
float b;
float c;
float d;
};
float get_c_exhaust_sysv64_ints(
void *a,
void *b,
void *c,
void *d,
void *e,
void *f,
// `f` used the last integer register, so `g` goes on the stack.
// It also used to bring the "count of available integer registers" down to
// `-1` which broke the next SSE-only aggregate argument (`h`) - see #62350.
void *g,
struct quad_floats h
) {
return h.c;
}
// Calculates the average of `(x + y) / n` where x: i64, y: f64. There must be exactly n pairs
// passed as variadic arguments. There are two versions of this function: the
// variadic one, and the one that takes a `va_list`.
double rust_valist_interesting_average(uint64_t n, va_list pairs) {
double sum = 0.0;
int i;
for(i = 0; i < n; i += 1) {
sum += (double)va_arg(pairs, int64_t);
sum += va_arg(pairs, double);
}
return sum / n;
}
double rust_interesting_average(uint64_t n, ...) {
double sum;
va_list pairs;
va_start(pairs, n);
sum = rust_valist_interesting_average(n, pairs);
va_end(pairs);
return sum;
}
int32_t rust_int8_to_int32(int8_t x) {
return (int32_t)x;
}
typedef union LARGE_INTEGER {
struct {
uint32_t LowPart;
uint32_t HighPart;
};
struct {
uint32_t LowPart;
uint32_t HighPart;
} u;
uint64_t QuadPart;
} LARGE_INTEGER;
LARGE_INTEGER increment_all_parts(LARGE_INTEGER li) {
li.LowPart += 1;
li.HighPart += 1;
li.u.LowPart += 1;
li.u.HighPart += 1;
li.QuadPart += 1;
return li;
}
#if __SIZEOF_INT128__ == 16
unsigned __int128 identity(unsigned __int128 a) {
return a;
}
__int128 square(__int128 a) {
return a * a;
}
__int128 sub(__int128 a, __int128 b) {
return a - b;
}
#endif
#define OPTION_TAG_NONE (0)
#define OPTION_TAG_SOME (1)
struct U8TaggedEnumOptionU64 {
uint8_t tag;
union {
uint64_t some;
};
};
struct U8TaggedEnumOptionU64
rust_dbg_new_some_u64(uint64_t some) {
struct U8TaggedEnumOptionU64 r = {
.tag = OPTION_TAG_SOME,
.some = some,
};
return r;
}
struct U8TaggedEnumOptionU64
rust_dbg_new_none_u64(void) {
struct U8TaggedEnumOptionU64 r = {
.tag = OPTION_TAG_NONE,
};
return r;
}
int32_t
rust_dbg_unpack_option_u64(struct U8TaggedEnumOptionU64 o, uint64_t *into) {
assert(into);
switch (o.tag) {
case OPTION_TAG_SOME:
*into = o.some;
return 1;
case OPTION_TAG_NONE:
return 0;
default:
assert(0 && "unexpected tag");
return 0;
}
}
struct U8TaggedEnumOptionU64U64 {
uint8_t tag;
union {
struct {
uint64_t a;
uint64_t b;
} some;
};
};
struct U8TaggedEnumOptionU64U64
rust_dbg_new_some_u64u64(uint64_t a, uint64_t b) {
struct U8TaggedEnumOptionU64U64 r = {
.tag = OPTION_TAG_SOME,
.some = { .a = a, .b = b },
};
return r;
}
struct U8TaggedEnumOptionU64U64
rust_dbg_new_none_u64u64(void) {
struct U8TaggedEnumOptionU64U64 r = {
.tag = OPTION_TAG_NONE,
};
return r;
}
int32_t
rust_dbg_unpack_option_u64u64(struct U8TaggedEnumOptionU64U64 o, uint64_t *a, uint64_t *b) {
assert(a);
assert(b);
switch (o.tag) {
case OPTION_TAG_SOME:
*a = o.some.a;
*b = o.some.b;
return 1;
case OPTION_TAG_NONE:
return 0;
default:
assert(0 && "unexpected tag");
return 0;
}
}
uint16_t issue_97463_leak_uninit_data(uint32_t a, uint32_t b, uint32_t c) {
struct bloc { uint16_t a; uint16_t b; uint16_t c; };
struct bloc *data = malloc(sizeof(struct bloc));
data->a = a & 0xFFFF;
data->b = b & 0xFFFF;
data->c = c & 0xFFFF;
return data->b; /* leak data */
}

View file

@ -1,20 +0,0 @@
// needs-asm-support
// compile-flags: -Ccodegen-units=1 -Zprint-mono-items=lazy --crate-type=lib
#[inline(always)]
pub unsafe fn f() {
//~ MONO_ITEM static f::S @@ asm_sym-cgu.0[External]
static S: usize = 1;
//~ MONO_ITEM fn f::fun @@ asm_sym-cgu.0[External]
fn fun() {}
core::arch::asm!("/* {0} {1} */", sym S, sym fun);
}
//~ MONO_ITEM fn g @@ asm_sym-cgu.0[External]
pub unsafe fn g() {
//~ MONO_ITEM static g::S @@ asm_sym-cgu.0[Internal]
static S: usize = 2;
//~ MONO_ITEM fn g::fun @@ asm_sym-cgu.0[Internal]
fn fun() {}
core::arch::asm!("/* {0} {1} */", sym S, sym fun);
}

View file

@ -1,24 +0,0 @@
#![crate_type = "lib"]
pub trait Trait : Sized {
fn without_self() -> u32;
fn without_self_default() -> u32 { 0 }
fn with_default_impl(self) -> Self { self }
fn with_default_impl_generic<T>(self, x: T) -> (Self, T) { (self, x) }
fn without_default_impl(x: u32) -> (Self, u32);
fn without_default_impl_generic<T>(x: T) -> (Self, T);
}
impl Trait for char {
fn without_self() -> u32 { 2 }
fn without_default_impl(x: u32) -> (Self, u32) { ('c', x) }
fn without_default_impl_generic<T>(x: T) -> (Self, T) { ('c', x) }
}
impl Trait for u32 {
fn without_self() -> u32 { 1 }
fn without_default_impl(x: u32) -> (Self, u32) { (0, x) }
fn without_default_impl_generic<T>(x: T) -> (Self, T) { (0, x) }
}

View file

@ -1,23 +0,0 @@
#![crate_type = "lib"]
#[inline]
pub fn inlined_fn(x: i32, y: i32) -> i32 {
let closure = |a, b| { a + b };
closure(x, y)
}
pub fn inlined_fn_generic<T>(x: i32, y: i32, z: T) -> (i32, T) {
let closure = |a, b| { a + b };
(closure(x, y), z)
}
pub fn non_inlined_fn(x: i32, y: i32) -> i32 {
let closure = |a, b| { a + b };
closure(x, y)
}

View file

@ -1,26 +0,0 @@
#![crate_type = "lib"]
struct Struct(u32);
#[inline(never)]
pub fn foo<T>(x: T) -> (T, u32, i8) {
let (x, Struct(y)) = bar(x);
(x, y, 2)
}
#[inline(never)]
fn bar<T>(x: T) -> (T, Struct) {
let _ = not_exported_and_not_generic(0);
(x, Struct(1))
}
// These should not contribute to the codegen items of other crates.
#[inline(never)]
pub fn exported_but_not_generic(x: i32) -> i64 {
x as i64
}
#[inline(never)]
fn not_exported_and_not_generic(x: u32) -> u64 {
x as u64
}

View file

@ -1,33 +0,0 @@
// In the current version of the collector that still has to support
// legacy-codegen, closures do not generate their own MonoItems, so we are
// ignoring this test until MIR codegen has taken over completely
// ignore-test
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
// aux-build:cgu_extern_closures.rs
extern crate cgu_extern_closures;
//~ MONO_ITEM fn cross_crate_closures::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn[0]::{{closure}}[0]
let _ = cgu_extern_closures::inlined_fn(1, 2);
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]<i32>
//~ MONO_ITEM fn cgu_extern_closures::inlined_fn_generic[0]::{{closure}}[0]<i32>
let _ = cgu_extern_closures::inlined_fn_generic(3, 4, 5i32);
// Nothing should be generated for this call, we just link to the instance
// in the extern crate.
let _ = cgu_extern_closures::non_inlined_fn(6, 7);
0
}
//~ MONO_ITEM drop-glue i8

View file

@ -1,24 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
// aux-build:cgu_generic_function.rs
extern crate cgu_generic_function;
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn cgu_generic_function::bar::<u32>
//~ MONO_ITEM fn cgu_generic_function::foo::<u32>
let _ = cgu_generic_function::foo(1u32);
//~ MONO_ITEM fn cgu_generic_function::bar::<u64>
//~ MONO_ITEM fn cgu_generic_function::foo::<u64>
let _ = cgu_generic_function::foo(2u64);
// This should not introduce a codegen item
let _ = cgu_generic_function::exported_but_not_generic(3);
0
}

View file

@ -1,50 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
// aux-build:cgu_export_trait_method.rs
extern crate cgu_export_trait_method;
use cgu_export_trait_method::Trait;
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
// The object code of these methods is contained in the external crate, so
// calling them should *not* introduce codegen items in the current crate.
let _: (u32, u32) = Trait::without_default_impl(0);
let _: (char, u32) = Trait::without_default_impl(0);
// Currently, no object code is generated for trait methods with default
// implementations, unless they are actually called from somewhere. Therefore
// we cannot import the implementations and have to create our own inline.
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl
let _ = Trait::with_default_impl(0u32);
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl
let _ = Trait::with_default_impl('c');
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<&str>
let _ = Trait::with_default_impl_generic(0u32, "abc");
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::with_default_impl_generic::<bool>
let _ = Trait::with_default_impl_generic(0u32, false);
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i16>
let _ = Trait::with_default_impl_generic('x', 1i16);
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::with_default_impl_generic::<i32>
let _ = Trait::with_default_impl_generic('y', 0i32);
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
let _: (u32, char) = Trait::without_default_impl_generic('c');
//~ MONO_ITEM fn <u32 as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
let _: (u32, bool) = Trait::without_default_impl_generic(false);
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<char>
let _: (char, char) = Trait::without_default_impl_generic('c');
//~ MONO_ITEM fn <char as cgu_export_trait_method::Trait>::without_default_impl_generic::<bool>
let _: (char, bool) = Trait::without_default_impl_generic(false);
0
}

View file

@ -1,36 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
#![feature(start)]
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDtor> - shim(Some(StructWithDtor)) @@ drop_in_place_intrinsic-cgu.0[Internal]
struct StructWithDtor(u32);
impl Drop for StructWithDtor {
//~ MONO_ITEM fn <StructWithDtor as std::ops::Drop>::drop
fn drop(&mut self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn std::ptr::drop_in_place::<[StructWithDtor; 2]> - shim(Some([StructWithDtor; 2])) @@ drop_in_place_intrinsic-cgu.0[Internal]
let x = [StructWithDtor(0), StructWithDtor(1)];
drop_slice_in_place(&x);
0
}
//~ MONO_ITEM fn drop_slice_in_place
fn drop_slice_in_place(x: &[StructWithDtor]) {
unsafe {
// This is the interesting thing in this test case: Normally we would
// not have drop-glue for the unsized [StructWithDtor]. This has to be
// generated though when the drop_in_place() intrinsic is used.
//~ MONO_ITEM fn std::ptr::drop_in_place::<[StructWithDtor]> - shim(Some([StructWithDtor])) @@ drop_in_place_intrinsic-cgu.0[Internal]
::std::ptr::drop_in_place(x as *const _ as *mut [StructWithDtor]);
}
}

View file

@ -1,40 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
fn take_fn_once<T1, T2, F: FnOnce(T1, T2)>(f: F, x: T1, y: T2) {
(f)(x, y)
}
fn function<T1, T2>(_: T1, _: T2) {}
fn take_fn_pointer<T1, T2>(f: fn(T1, T2), x: T1, y: T2) {
(f)(x, y)
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn take_fn_once::<u32, &str, fn(u32, &str) {function::<u32, &str>}>
//~ MONO_ITEM fn function::<u32, &str>
//~ MONO_ITEM fn <fn(u32, &str) {function::<u32, &str>} as std::ops::FnOnce<(u32, &str)>>::call_once - shim(fn(u32, &str) {function::<u32, &str>})
take_fn_once(function, 0u32, "abc");
//~ MONO_ITEM fn take_fn_once::<char, f64, fn(char, f64) {function::<char, f64>}>
//~ MONO_ITEM fn function::<char, f64>
//~ MONO_ITEM fn <fn(char, f64) {function::<char, f64>} as std::ops::FnOnce<(char, f64)>>::call_once - shim(fn(char, f64) {function::<char, f64>})
take_fn_once(function, 'c', 0f64);
//~ MONO_ITEM fn take_fn_pointer::<i32, ()>
//~ MONO_ITEM fn function::<i32, ()>
take_fn_pointer(function, 0i32, ());
//~ MONO_ITEM fn take_fn_pointer::<f32, i64>
//~ MONO_ITEM fn function::<f32, i64>
take_fn_pointer(function, 0f32, 0i64);
0
}

View file

@ -1,91 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
#![deny(dead_code)]
#![feature(start)]
struct StructWithDrop<T1, T2> {
x: T1,
y: T2,
}
impl<T1, T2> Drop for StructWithDrop<T1, T2> {
fn drop(&mut self) {}
}
struct StructNoDrop<T1, T2> {
x: T1,
y: T2,
}
enum EnumWithDrop<T1, T2> {
A(T1),
B(T2)
}
impl<T1, T2> Drop for EnumWithDrop<T1, T2> {
fn drop(&mut self) {}
}
enum EnumNoDrop<T1, T2> {
A(T1),
B(T2)
}
struct NonGenericNoDrop(#[allow(unused_tuple_struct_fields)] i32);
struct NonGenericWithDrop(#[allow(unused_tuple_struct_fields)] i32);
//~ MONO_ITEM fn std::ptr::drop_in_place::<NonGenericWithDrop> - shim(Some(NonGenericWithDrop)) @@ generic_drop_glue-cgu.0[Internal]
impl Drop for NonGenericWithDrop {
//~ MONO_ITEM fn <NonGenericWithDrop as std::ops::Drop>::drop
fn drop(&mut self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop<i8, char>> - shim(Some(StructWithDrop<i8, char>)) @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <StructWithDrop<i8, char> as std::ops::Drop>::drop
let _ = StructWithDrop { x: 0i8, y: 'a' }.x;
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop<&str, NonGenericNoDrop>> - shim(Some(StructWithDrop<&str, NonGenericNoDrop>)) @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <StructWithDrop<&str, NonGenericNoDrop> as std::ops::Drop>::drop
let _ = StructWithDrop { x: "&str", y: NonGenericNoDrop(0) }.y;
// Should produce no drop glue
let _ = StructNoDrop { x: 'a', y: 0u32 }.x;
// This is supposed to generate drop-glue because it contains a field that
// needs to be dropped.
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructNoDrop<NonGenericWithDrop, f64>> - shim(Some(StructNoDrop<NonGenericWithDrop, f64>)) @@ generic_drop_glue-cgu.0[Internal]
let _ = StructNoDrop { x: NonGenericWithDrop(0), y: 0f64 }.y;
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop<i32, i64>> - shim(Some(EnumWithDrop<i32, i64>)) @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <EnumWithDrop<i32, i64> as std::ops::Drop>::drop
let _ = match EnumWithDrop::A::<i32, i64>(0) {
EnumWithDrop::A(x) => x,
EnumWithDrop::B(x) => x as i32
};
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop<f64, f32>> - shim(Some(EnumWithDrop<f64, f32>)) @@ generic_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <EnumWithDrop<f64, f32> as std::ops::Drop>::drop
let _ = match EnumWithDrop::B::<f64, f32>(1.0) {
EnumWithDrop::A(x) => x,
EnumWithDrop::B(x) => x as f64
};
let _ = match EnumNoDrop::A::<i32, i64>(0) {
EnumNoDrop::A(x) => x,
EnumNoDrop::B(x) => x as i32
};
let _ = match EnumNoDrop::B::<f64, f32>(1.0) {
EnumNoDrop::A(x) => x,
EnumNoDrop::B(x) => x as f64
};
0
}

View file

@ -1,55 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
fn foo1<T1>(a: T1) -> (T1, u32) {
(a, 1)
}
fn foo2<T1, T2>(a: T1, b: T2) -> (T1, T2) {
(a, b)
}
fn foo3<T1, T2, T3>(a: T1, b: T2, c: T3) -> (T1, T2, T3) {
(a, b, c)
}
// This function should be instantiated even if no used
//~ MONO_ITEM fn lifetime_only
pub fn lifetime_only<'a>(a: &'a u32) -> &'a u32 {
a
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn foo1::<i32>
let _ = foo1(2i32);
//~ MONO_ITEM fn foo1::<i64>
let _ = foo1(2i64);
//~ MONO_ITEM fn foo1::<&str>
let _ = foo1("abc");
//~ MONO_ITEM fn foo1::<char>
let _ = foo1('v');
//~ MONO_ITEM fn foo2::<i32, i32>
let _ = foo2(2i32, 2i32);
//~ MONO_ITEM fn foo2::<i64, &str>
let _ = foo2(2i64, "abc");
//~ MONO_ITEM fn foo2::<&str, usize>
let _ = foo2("a", 2usize);
//~ MONO_ITEM fn foo2::<char, ()>
let _ = foo2('v', ());
//~ MONO_ITEM fn foo3::<i32, i32, i32>
let _ = foo3(2i32, 2i32, 2i32);
//~ MONO_ITEM fn foo3::<i64, &str, char>
let _ = foo3(2i64, "abc", 'c');
//~ MONO_ITEM fn foo3::<i16, &str, usize>
let _ = foo3(0i16, "a", 2usize);
//~ MONO_ITEM fn foo3::<char, (), ()>
let _ = foo3('v', (), ());
0
}

View file

@ -1,71 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
struct Struct<T> {
x: T,
f: fn(x: T) -> T,
}
fn id<T>(x: T) -> T { x }
impl<T> Struct<T> {
fn new(x: T) -> Struct<T> {
Struct {
x: x,
f: id
}
}
fn get<T2>(self, x: T2) -> (T, T2) {
(self.x, x)
}
}
pub struct LifeTimeOnly<'a> {
_a: &'a u32
}
impl<'a> LifeTimeOnly<'a> {
//~ MONO_ITEM fn LifeTimeOnly::<'_>::foo
pub fn foo(&self) {}
//~ MONO_ITEM fn LifeTimeOnly::<'_>::bar
pub fn bar(&'a self) {}
//~ MONO_ITEM fn LifeTimeOnly::<'_>::baz
pub fn baz<'b>(&'b self) {}
pub fn non_instantiated<T>(&self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn Struct::<i32>::new
//~ MONO_ITEM fn id::<i32>
//~ MONO_ITEM fn Struct::<i32>::get::<i16>
let _ = Struct::new(0i32).get(0i16);
//~ MONO_ITEM fn Struct::<i64>::new
//~ MONO_ITEM fn id::<i64>
//~ MONO_ITEM fn Struct::<i64>::get::<i16>
let _ = Struct::new(0i64).get(0i16);
//~ MONO_ITEM fn Struct::<char>::new
//~ MONO_ITEM fn id::<char>
//~ MONO_ITEM fn Struct::<char>::get::<i16>
let _ = Struct::new('c').get(0i16);
//~ MONO_ITEM fn Struct::<&str>::new
//~ MONO_ITEM fn id::<&str>
//~ MONO_ITEM fn Struct::<Struct<&str>>::get::<i16>
let _ = Struct::new(Struct::new("str")).get(0i16);
//~ MONO_ITEM fn Struct::<Struct<&str>>::new
//~ MONO_ITEM fn id::<Struct<&str>>
let _ = (Struct::new(Struct::new("str")).f)(Struct::new("str"));
0
}

View file

@ -1,27 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
trait SomeTrait {
fn foo(&self);
}
// This function is never instantiated but the contained impl must still be
// discovered.
pub fn generic_function<T>(x: T) -> (T, i32) {
impl SomeTrait for i64 {
//~ MONO_ITEM fn generic_function::<impl SomeTrait for i64>::foo
fn foo(&self) {}
}
(x, 0)
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
0i64.foo();
0
}

View file

@ -1,58 +0,0 @@
// compile-flags:-Zprint-mono-items=lazy
// rust-lang/rust#90405
// Ensure implicit panic calls are collected
#![feature(lang_items)]
#![feature(no_core)]
#![crate_type = "lib"]
#![no_core]
#![no_std]
#[lang = "panic_location"]
struct Location<'a> {
_file: &'a str,
_line: u32,
_col: u32,
}
#[lang = "panic"]
#[inline]
#[track_caller]
fn panic(_: &'static str) -> ! {
loop {}
}
#[lang = "sized"]
trait Sized {}
#[lang = "copy"]
trait Copy {}
#[lang = "freeze"]
trait Freeze {}
impl Copy for i32 {}
#[lang = "div"]
trait Div<Rhs = Self> {
type Output;
fn div(self, rhs: Rhs) -> Self::Output;
}
impl Div for i32 {
type Output = i32;
fn div(self, rhs: i32) -> i32 {
self / rhs
}
}
#[allow(unconditional_panic)]
pub fn foo() {
// This implicitly generates a panic call.
let _ = 1 / 0;
}
//~ MONO_ITEM fn foo
//~ MONO_ITEM fn <i32 as Div>::div
//~ MONO_ITEM fn panic

View file

@ -1,38 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager -Zinline-in-all-cgus -Zmir-opt-level=0
#![deny(dead_code)]
#![feature(start)]
trait Trait {
fn foo(&self) -> u32;
fn bar(&self);
}
struct Struct<T> {
_a: T
}
impl<T> Trait for Struct<T> {
fn foo(&self) -> u32 { 0 }
fn bar(&self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
let s1 = Struct { _a: 0u32 };
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u32>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn <Struct<u32> as Trait>::foo
//~ MONO_ITEM fn <Struct<u32> as Trait>::bar
let _ = &s1 as &Trait;
let s1 = Struct { _a: 0u64 };
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct<u64>> - shim(None) @@ instantiation_through_vtable-cgu.0[Internal]
//~ MONO_ITEM fn <Struct<u64> as Trait>::foo
//~ MONO_ITEM fn <Struct<u64> as Trait>::bar
let _ = &s1 as &Trait;
0
}

View file

@ -1,35 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
fn generic_fn<T>(a: T) -> (T, i32) {
//~ MONO_ITEM fn generic_fn::nested_fn
fn nested_fn(a: i32) -> i32 {
a + 1
}
let x = {
//~ MONO_ITEM fn generic_fn::nested_fn
fn nested_fn(a: i32) -> i32 {
a + 2
}
1 + nested_fn(1)
};
return (a, x + nested_fn(0));
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn generic_fn::<i64>
let _ = generic_fn(0i64);
//~ MONO_ITEM fn generic_fn::<u16>
let _ = generic_fn(0u16);
//~ MONO_ITEM fn generic_fn::<i8>
let _ = generic_fn(0i8);
0
}

View file

@ -1,60 +0,0 @@
// In the current version of the collector that still has to support
// legacy-codegen, closures do not generate their own MonoItems, so we are
// ignoring this test until MIR codegen has taken over completely
// ignore-test
//
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
//~ MONO_ITEM fn non_generic_closures::temporary[0]
fn temporary() {
//~ MONO_ITEM fn non_generic_closures::temporary[0]::{{closure}}[0]
(|a: u32| {
let _ = a;
})(4);
}
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]
fn assigned_to_variable_but_not_executed() {
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_but_not_executed[0]::{{closure}}[0]
let _x = |a: i16| {
let _ = a + 1;
};
}
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]
fn assigned_to_variable_executed_indirectly() {
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_directly[0]::{{closure}}[0]
let f = |a: i32| {
let _ = a + 2;
};
run_closure(&f);
}
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]
fn assigned_to_variable_executed_directly() {
//~ MONO_ITEM fn non_generic_closures::assigned_to_variable_executed_indirectly[0]::{{closure}}[0]
let f = |a: i64| {
let _ = a + 3;
};
f(4);
}
//~ MONO_ITEM fn non_generic_closures::start[0]
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
temporary();
assigned_to_variable_but_not_executed();
assigned_to_variable_executed_directly();
assigned_to_variable_executed_indirectly();
0
}
//~ MONO_ITEM fn non_generic_closures::run_closure[0]
fn run_closure(f: &Fn(i32)) {
f(3);
}

View file

@ -1,49 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
#![deny(dead_code)]
#![feature(start)]
//~ MONO_ITEM fn std::ptr::drop_in_place::<StructWithDrop> - shim(Some(StructWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
struct StructWithDrop {
x: i32
}
impl Drop for StructWithDrop {
//~ MONO_ITEM fn <StructWithDrop as std::ops::Drop>::drop
fn drop(&mut self) {}
}
struct StructNoDrop {
x: i32
}
//~ MONO_ITEM fn std::ptr::drop_in_place::<EnumWithDrop> - shim(Some(EnumWithDrop)) @@ non_generic_drop_glue-cgu.0[Internal]
enum EnumWithDrop {
A(i32)
}
impl Drop for EnumWithDrop {
//~ MONO_ITEM fn <EnumWithDrop as std::ops::Drop>::drop
fn drop(&mut self) {}
}
enum EnumNoDrop {
A(i32)
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
let _ = StructWithDrop { x: 0 }.x;
let _ = StructNoDrop { x: 0 }.x;
let _ = match EnumWithDrop::A(0) {
EnumWithDrop::A(x) => x
};
let _ = match EnumNoDrop::A(0) {
EnumNoDrop::A(x) => x
};
0
}

View file

@ -1,72 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
//~ MONO_ITEM fn foo
fn foo() {
{
//~ MONO_ITEM fn foo::foo
fn foo() {}
foo();
}
{
//~ MONO_ITEM fn foo::foo
fn foo() {}
foo();
}
}
//~ MONO_ITEM fn bar
fn bar() {
//~ MONO_ITEM fn bar::baz
fn baz() {}
baz();
}
struct Struct { _x: i32 }
impl Struct {
//~ MONO_ITEM fn Struct::foo
fn foo() {
{
//~ MONO_ITEM fn Struct::foo::foo
fn foo() {}
foo();
}
{
//~ MONO_ITEM fn Struct::foo::foo
fn foo() {}
foo();
}
}
//~ MONO_ITEM fn Struct::bar
fn bar(&self) {
{
//~ MONO_ITEM fn Struct::bar::foo
fn foo() {}
foo();
}
{
//~ MONO_ITEM fn Struct::bar::foo
fn foo() {}
foo();
}
}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
foo();
bar();
Struct::foo();
let x = Struct { _x: 0 };
x.bar();
0
}

View file

@ -1,59 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![crate_type="lib"]
use std::ops::{Index, IndexMut, Add, Deref};
pub struct Indexable {
data: [u8; 3]
}
impl Index<usize> for Indexable {
type Output = u8;
//~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index
fn index(&self, index: usize) -> &Self::Output {
if index >= 3 {
&self.data[0]
} else {
&self.data[index]
}
}
}
impl IndexMut<usize> for Indexable {
//~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
if index >= 3 {
&mut self.data[0]
} else {
&mut self.data[index]
}
}
}
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne
#[derive(PartialEq)]
pub struct Equatable(u32);
impl Add<u32> for Equatable {
type Output = u32;
//~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add
fn add(self, rhs: u32) -> u32 {
self.0 + rhs
}
}
impl Deref for Equatable {
type Target = u32;
//~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref
fn deref(&self) -> &Self::Target {
&self.0
}
}

View file

@ -1,16 +0,0 @@
// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
#![feature(start)]
pub static FN : fn() = foo::<i32>;
pub fn foo<T>() { }
//~ MONO_ITEM fn foo::<T>
//~ MONO_ITEM static FN
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
0
}

View file

@ -1,54 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
static STATIC1: i64 = {
const STATIC1_CONST1: i64 = 2;
1 + CONST1 as i64 + STATIC1_CONST1
};
const CONST1: i64 = {
const CONST1_1: i64 = {
const CONST1_1_1: i64 = 2;
CONST1_1_1 + 1
};
1 + CONST1_1 as i64
};
fn foo() {
let _ = {
const CONST2: i64 = 0;
static STATIC2: i64 = CONST2;
let x = {
const CONST2: i64 = 1;
static STATIC2: i64 = CONST2;
STATIC2
};
x + STATIC2
};
let _ = {
const CONST2: i64 = 0;
static STATIC2: i64 = CONST2;
STATIC2
};
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
foo();
let _ = STATIC1;
0
}
//~ MONO_ITEM static STATIC1
//~ MONO_ITEM fn foo
//~ MONO_ITEM static foo::STATIC2
//~ MONO_ITEM static foo::STATIC2
//~ MONO_ITEM static foo::STATIC2

View file

@ -1,73 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
pub trait SomeTrait {
fn foo(&self);
fn bar<T>(&self, x: T);
}
impl SomeTrait for i64 {
//~ MONO_ITEM fn <i64 as SomeTrait>::foo
fn foo(&self) {}
fn bar<T>(&self, _: T) {}
}
impl SomeTrait for i32 {
//~ MONO_ITEM fn <i32 as SomeTrait>::foo
fn foo(&self) {}
fn bar<T>(&self, _: T) {}
}
pub trait SomeGenericTrait<T> {
fn foo(&self, x: T);
fn bar<T2>(&self, x: T, y: T2);
}
// Concrete impl of generic trait
impl SomeGenericTrait<u32> for f64 {
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::foo
fn foo(&self, _: u32) {}
fn bar<T2>(&self, _: u32, _: T2) {}
}
// Generic impl of generic trait
impl<T> SomeGenericTrait<T> for f32 {
fn foo(&self, _: T) {}
fn bar<T2>(&self, _: T, _: T2) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn <i32 as SomeTrait>::bar::<char>
0i32.bar('x');
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<&str>
0f64.bar(0u32, "&str");
//~ MONO_ITEM fn <f64 as SomeGenericTrait<u32>>::bar::<()>
0f64.bar(0u32, ());
//~ MONO_ITEM fn <f32 as SomeGenericTrait<char>>::foo
0f32.foo('x');
//~ MONO_ITEM fn <f32 as SomeGenericTrait<i64>>::foo
0f32.foo(-1i64);
//~ MONO_ITEM fn <f32 as SomeGenericTrait<u32>>::bar::<()>
0f32.bar(0u32, ());
//~ MONO_ITEM fn <f32 as SomeGenericTrait<&str>>::bar::<&str>
0f32.bar("&str", "&str");
0
}

View file

@ -1,60 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
#![deny(dead_code)]
#![feature(start)]
trait Trait : Sized {
fn foo(self) -> Self { self }
}
impl Trait for u32 {
fn foo(self) -> u32 { self }
}
impl Trait for char {
}
fn take_foo_once<T, F: FnOnce(T) -> T>(f: F, arg: T) -> T {
(f)(arg)
}
fn take_foo<T, F: Fn(T) -> T>(f: F, arg: T) -> T {
(f)(arg)
}
fn take_foo_mut<T, F: FnMut(T) -> T>(mut f: F, arg: T) -> T {
(f)(arg)
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn take_foo_once::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
//~ MONO_ITEM fn <u32 as Trait>::foo
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnOnce<(u32,)>>::call_once - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
take_foo_once(Trait::foo, 0u32);
//~ MONO_ITEM fn take_foo_once::<char, fn(char) -> char {<char as Trait>::foo}>
//~ MONO_ITEM fn <char as Trait>::foo
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnOnce<(char,)>>::call_once - shim(fn(char) -> char {<char as Trait>::foo})
take_foo_once(Trait::foo, 'c');
//~ MONO_ITEM fn take_foo::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::Fn<(u32,)>>::call - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
take_foo(Trait::foo, 0u32);
//~ MONO_ITEM fn take_foo::<char, fn(char) -> char {<char as Trait>::foo}>
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::Fn<(char,)>>::call - shim(fn(char) -> char {<char as Trait>::foo})
take_foo(Trait::foo, 'c');
//~ MONO_ITEM fn take_foo_mut::<u32, fn(u32) -> u32 {<u32 as Trait>::foo}>
//~ MONO_ITEM fn <fn(u32) -> u32 {<u32 as Trait>::foo} as std::ops::FnMut<(u32,)>>::call_mut - shim(fn(u32) -> u32 {<u32 as Trait>::foo})
take_foo_mut(Trait::foo, 0u32);
//~ MONO_ITEM fn take_foo_mut::<char, fn(char) -> char {<char as Trait>::foo}>
//~ MONO_ITEM fn <fn(char) -> char {<char as Trait>::foo} as std::ops::FnMut<(char,)>>::call_mut - shim(fn(char) -> char {<char as Trait>::foo})
take_foo_mut(Trait::foo, 'c');
0
}

View file

@ -1,61 +0,0 @@
// compile-flags:-Zprint-mono-items=eager -Zpolymorphize=on
#![deny(dead_code)]
#![feature(start)]
trait SomeTrait {
fn foo(&self) { }
fn bar<T>(&self, x: T) -> T { x }
}
impl SomeTrait for i8 {
// take the default implementations
// For the non-generic foo(), we should generate a codegen-item even if it
// is not called anywhere
//~ MONO_ITEM fn <i8 as SomeTrait>::foo
}
trait SomeGenericTrait<T1> {
fn foo(&self) { }
fn bar<T2>(&self, x: T1, y: T2) {}
}
// Non-generic impl of generic trait
impl SomeGenericTrait<u64> for i32 {
// take the default implementations
// For the non-generic foo(), we should generate a codegen-item even if it
// is not called anywhere
//~ MONO_ITEM fn <i32 as SomeGenericTrait<T1>>::foo
}
// Non-generic impl of generic trait
impl<T1> SomeGenericTrait<T1> for u32 {
// take the default implementations
// since nothing is monomorphic here, nothing should be generated unless used somewhere.
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn <i8 as SomeTrait>::bar::<char>
let _ = 1i8.bar('c');
//~ MONO_ITEM fn <i8 as SomeTrait>::bar::<&str>
let _ = 2i8.bar("&str");
//~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<char>
0i32.bar(0u64, 'c');
//~ MONO_ITEM fn <i32 as SomeGenericTrait<u64>>::bar::<&str>
0i32.bar(0u64, "&str");
//~ MONO_ITEM fn <u32 as SomeGenericTrait<i8>>::bar::<&[char; 1]>
0u32.bar(0i8, &['c']);
//~ MONO_ITEM fn <u32 as SomeGenericTrait<i16>>::bar::<()>
0u32.bar(0i16, ());
0
}

View file

@ -1,46 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
#![deny(dead_code)]
#![feature(start)]
//~ MONO_ITEM fn std::ptr::drop_in_place::<Root> - shim(Some(Root)) @@ transitive_drop_glue-cgu.0[Internal]
struct Root(#[allow(unused_tuple_struct_fields)] Intermediate);
//~ MONO_ITEM fn std::ptr::drop_in_place::<Intermediate> - shim(Some(Intermediate)) @@ transitive_drop_glue-cgu.0[Internal]
struct Intermediate(#[allow(unused_tuple_struct_fields)] Leaf);
//~ MONO_ITEM fn std::ptr::drop_in_place::<Leaf> - shim(Some(Leaf)) @@ transitive_drop_glue-cgu.0[Internal]
struct Leaf;
impl Drop for Leaf {
//~ MONO_ITEM fn <Leaf as std::ops::Drop>::drop
fn drop(&mut self) {}
}
struct RootGen<T>(#[allow(unused_tuple_struct_fields)] IntermediateGen<T>);
struct IntermediateGen<T>(#[allow(unused_tuple_struct_fields)] LeafGen<T>);
struct LeafGen<T>(#[allow(unused_tuple_struct_fields)] T);
impl<T> Drop for LeafGen<T> {
fn drop(&mut self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
let _ = Root(Intermediate(Leaf));
//~ MONO_ITEM fn std::ptr::drop_in_place::<RootGen<u32>> - shim(Some(RootGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn std::ptr::drop_in_place::<IntermediateGen<u32>> - shim(Some(IntermediateGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn std::ptr::drop_in_place::<LeafGen<u32>> - shim(Some(LeafGen<u32>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <LeafGen<u32> as std::ops::Drop>::drop
let _ = RootGen(IntermediateGen(LeafGen(0u32)));
//~ MONO_ITEM fn std::ptr::drop_in_place::<RootGen<i16>> - shim(Some(RootGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn std::ptr::drop_in_place::<IntermediateGen<i16>> - shim(Some(IntermediateGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn std::ptr::drop_in_place::<LeafGen<i16>> - shim(Some(LeafGen<i16>)) @@ transitive_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn <LeafGen<i16> as std::ops::Drop>::drop
let _ = RootGen(IntermediateGen(LeafGen(0i16)));
0
}

View file

@ -1,27 +0,0 @@
//
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
#![deny(dead_code)]
#![feature(start)]
//~ MONO_ITEM fn std::ptr::drop_in_place::<Dropped> - shim(Some(Dropped)) @@ tuple_drop_glue-cgu.0[Internal]
struct Dropped;
impl Drop for Dropped {
//~ MONO_ITEM fn <Dropped as std::ops::Drop>::drop
fn drop(&mut self) {}
}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Dropped)> - shim(Some((u32, Dropped))) @@ tuple_drop_glue-cgu.0[Internal]
let x = (0u32, Dropped);
//~ MONO_ITEM fn std::ptr::drop_in_place::<(i16, (Dropped, bool))> - shim(Some((i16, (Dropped, bool)))) @@ tuple_drop_glue-cgu.0[Internal]
//~ MONO_ITEM fn std::ptr::drop_in_place::<(Dropped, bool)> - shim(Some((Dropped, bool))) @@ tuple_drop_glue-cgu.0[Internal]
let x = (0i16, (Dropped, true));
0
}

View file

@ -1,9 +0,0 @@
// compile-flags:-Zprint-mono-items=lazy
#![deny(dead_code)]
#![crate_type = "rlib"]
//~ MONO_ITEM fn foo @@ unreferenced_const_fn-cgu.0[External]
pub const fn foo(x: u32) -> u32 {
x + 0xf00
}

View file

@ -1,11 +0,0 @@
// compile-flags:-Zprint-mono-items=lazy
// N.B., we do not expect *any* monomorphization to be generated here.
#![deny(dead_code)]
#![crate_type = "rlib"]
#[inline]
pub fn foo() -> bool {
[1, 2] == [3, 4]
}

View file

@ -1,79 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
// compile-flags:-Zinline-in-all-cgus
// compile-flags:-Zmir-opt-level=0
#![deny(dead_code)]
#![feature(coerce_unsized)]
#![feature(unsize)]
#![feature(start)]
use std::marker::Unsize;
use std::ops::CoerceUnsized;
trait Trait {
fn foo(&self);
}
// Simple Case
impl Trait for bool {
fn foo(&self) {}
}
impl Trait for char {
fn foo(&self) {}
}
// Struct Field Case
struct Struct<T: ?Sized> {
_a: u32,
_b: i32,
_c: T
}
impl Trait for f64 {
fn foo(&self) {}
}
// Custom Coercion Case
impl Trait for u32 {
fn foo(&self) {}
}
#[derive(Clone, Copy)]
struct Wrapper<T: ?Sized>(#[allow(unused_tuple_struct_fields)] *const T);
impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Wrapper<U>> for Wrapper<T> {}
//~ MONO_ITEM fn start
#[start]
fn start(_: isize, _: *const *const u8) -> isize {
// simple case
let bool_sized = &true;
//~ MONO_ITEM fn std::ptr::drop_in_place::<bool> - shim(None) @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn <bool as Trait>::foo
let _bool_unsized = bool_sized as &Trait;
let char_sized = &'a';
//~ MONO_ITEM fn std::ptr::drop_in_place::<char> - shim(None) @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn <char as Trait>::foo
let _char_unsized = char_sized as &Trait;
// struct field
let struct_sized = &Struct {
_a: 1,
_b: 2,
_c: 3.0f64
};
//~ MONO_ITEM fn std::ptr::drop_in_place::<f64> - shim(None) @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn <f64 as Trait>::foo
let _struct_unsized = struct_sized as &Struct<Trait>;
// custom coercion
let wrapper_sized = Wrapper(&0u32);
//~ MONO_ITEM fn std::ptr::drop_in_place::<u32> - shim(None) @@ unsizing-cgu.0[Internal]
//~ MONO_ITEM fn <u32 as Trait>::foo
let _wrapper_sized = wrapper_sized as Wrapper<Trait>;
0
}

View file

@ -1,77 +0,0 @@
// compile-flags:-Zprint-mono-items=eager
#![crate_type="lib"]
#![deny(dead_code)]
// This test asserts that no codegen items are generated for generic items that
// are never instantiated in the local crate.
pub trait Trait {
fn foo() {}
fn bar(&self) {}
}
pub fn foo<T: Copy>(x: T) -> (T, T) {
(x, x)
}
pub struct Struct<T> {
x: T
}
impl<T> Struct<T> {
pub fn foo(self) -> T {
self.x
}
pub fn bar() {}
}
pub enum Enum<T> {
A(T),
B { x: T }
}
impl<T> Enum<T> {
pub fn foo(self) -> T {
match self {
Enum::A(x) => x,
Enum::B { x } => x,
}
}
pub fn bar() {}
}
pub struct TupleStruct<T>(T);
impl<T> TupleStruct<T> {
pub fn foo(self) -> T {
self.0
}
pub fn bar() {}
}
pub type Pair<T> = (T, T);
pub struct NonGeneric {
x: i32
}
impl NonGeneric {
pub fn foo(self) -> i32 {
self.x
}
pub fn generic_foo<T>(&self, x: T) -> (T, i32) {
(x, self.x)
}
pub fn generic_bar<T: Copy>(x: T) -> (T, T) {
(x, x)
}
}
// Only the non-generic methods should be instantiated:
//~ MONO_ITEM fn NonGeneric::foo

View file

@ -1,10 +0,0 @@
#![crate_type = "lib"]
#[inline]
pub fn inlined() {}
#[inline(always)]
pub fn always_inlined() {}
#[inline(never)]
pub fn never_inlined() {}

View file

@ -1,7 +0,0 @@
#![crate_type = "lib"]
pub struct Struct(pub u32);
impl Drop for Struct {
fn drop(&mut self) {}
}

View file

@ -1,26 +0,0 @@
#![crate_type = "lib"]
struct Struct(u32);
#[inline(never)]
pub fn foo<T>(x: T) -> (T, u32, i8) {
let (x, Struct(y)) = bar(x);
(x, y, 2)
}
#[inline(never)]
fn bar<T>(x: T) -> (T, Struct) {
let _ = not_exported_and_not_generic(0);
(x, Struct(1))
}
// These should not contribute to the codegen items of other crates.
#[inline(never)]
pub fn exported_but_not_generic(x: i32) -> i64 {
x as i64
}
#[inline(never)]
fn not_exported_and_not_generic(x: u32) -> u64 {
x as u64
}

View file

@ -1,26 +0,0 @@
// NOTE: We always compile this test with -Copt-level=0 because higher opt-levels
// prevent drop-glue from participating in share-generics.
// compile-flags:-Zshare-generics=yes -Copt-level=0
// no-prefer-dynamic
#![crate_type="rlib"]
pub fn generic_fn<T>(x: T, y: T) -> (T, T) {
(x, y)
}
pub fn use_generic_fn_f32() -> (f32, f32) {
// This line causes drop glue for Foo to be instantiated. We want to make
// sure that this crate exports an instance to be re-used by share-generics.
let _ = Foo(0);
generic_fn(0.0f32, 1.0f32)
}
pub struct Foo(pub u32);
impl Drop for Foo {
fn drop(&mut self) {
println!("foo");
}
}

View file

@ -1,36 +0,0 @@
//
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
// incremental
// compile-flags:-Zprint-mono-items=lazy
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
#![allow(dead_code)]
#![crate_type = "rlib"]
// aux-build:cgu_extern_drop_glue.rs
extern crate cgu_extern_drop_glue;
//~ MONO_ITEM fn std::ptr::drop_in_place::<cgu_extern_drop_glue::Struct> - shim(Some(cgu_extern_drop_glue::Struct)) @@ extern_drop_glue-fallback.cgu[External]
struct LocalStruct(cgu_extern_drop_glue::Struct);
//~ MONO_ITEM fn user @@ extern_drop_glue[External]
pub fn user() {
//~ MONO_ITEM fn std::ptr::drop_in_place::<LocalStruct> - shim(Some(LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
pub mod mod1 {
use cgu_extern_drop_glue;
struct LocalStruct(cgu_extern_drop_glue::Struct);
//~ MONO_ITEM fn mod1::user @@ extern_drop_glue-mod1[External]
pub fn user() {
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::LocalStruct> - shim(Some(mod1::LocalStruct)) @@ extern_drop_glue-fallback.cgu[External]
let _ = LocalStruct(cgu_extern_drop_glue::Struct(0));
}
}

View file

@ -1,53 +0,0 @@
//
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// incremental
// compile-flags:-Zprint-mono-items=eager -Zshare-generics=y
#![allow(dead_code)]
#![crate_type="lib"]
// aux-build:cgu_generic_function.rs
extern crate cgu_generic_function;
//~ MONO_ITEM fn user @@ extern_generic[Internal]
fn user() {
let _ = cgu_generic_function::foo("abc");
}
mod mod1 {
use cgu_generic_function;
//~ MONO_ITEM fn mod1::user @@ extern_generic-mod1[Internal]
fn user() {
let _ = cgu_generic_function::foo("abc");
}
mod mod1 {
use cgu_generic_function;
//~ MONO_ITEM fn mod1::mod1::user @@ extern_generic-mod1-mod1[Internal]
fn user() {
let _ = cgu_generic_function::foo("abc");
}
}
}
mod mod2 {
use cgu_generic_function;
//~ MONO_ITEM fn mod2::user @@ extern_generic-mod2[Internal]
fn user() {
let _ = cgu_generic_function::foo("abc");
}
}
mod mod3 {
//~ MONO_ITEM fn mod3::non_user @@ extern_generic-mod3[Internal]
fn non_user() {}
}
// Make sure the two generic functions from the extern crate get instantiated
// once for the current crate
//~ MONO_ITEM fn cgu_generic_function::foo::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]
//~ MONO_ITEM fn cgu_generic_function::bar::<&str> @@ cgu_generic_function-in-extern_generic.volatile[External]

View file

@ -1,42 +0,0 @@
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// incremental
// compile-flags:-Zprint-mono-items=lazy
// compile-flags:-Ccodegen-units=3
#![crate_type = "rlib"]
// This test makes sure that merging of CGUs works together with incremental
// compilation but at the same time does not modify names of CGUs that were not
// affected by merging.
//
// We expect CGUs `aaa` and `bbb` to be merged (because they are the smallest),
// while `ccc` and `ddd` are supposed to stay untouched.
pub mod aaa {
//~ MONO_ITEM fn aaa::foo @@ incremental_merging-aaa--incremental_merging-bbb[External]
pub fn foo(a: u64) -> u64 {
a + 1
}
}
pub mod bbb {
//~ MONO_ITEM fn bbb::foo @@ incremental_merging-aaa--incremental_merging-bbb[External]
pub fn foo(a: u64, b: u64) -> u64 {
a + b + 1
}
}
pub mod ccc {
//~ MONO_ITEM fn ccc::foo @@ incremental_merging-ccc[External]
pub fn foo(a: u64, b: u64, c: u64) -> u64 {
a + b + c + 1
}
}
pub mod ddd {
//~ MONO_ITEM fn ddd::foo @@ incremental_merging-ddd[External]
pub fn foo(a: u64, b: u64, c: u64, d: u64) -> u64 {
a + b + c + d + 1
}
}

View file

@ -1,53 +0,0 @@
//
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// incremental
// compile-flags:-Zprint-mono-items=lazy
// compile-flags:-Zinline-in-all-cgus
#![crate_type="lib"]
// aux-build:cgu_explicit_inlining.rs
extern crate cgu_explicit_inlining;
// This test makes sure that items inlined from external crates are privately
// instantiated in every codegen unit they are used in.
//~ MONO_ITEM fn cgu_explicit_inlining::inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod1[Internal]
//~ MONO_ITEM fn cgu_explicit_inlining::always_inlined @@ inlining_from_extern_crate[Internal] inlining_from_extern_crate-mod2[Internal]
//~ MONO_ITEM fn user @@ inlining_from_extern_crate[External]
pub fn user()
{
cgu_explicit_inlining::inlined();
cgu_explicit_inlining::always_inlined();
// does not generate a monomorphization in this crate
cgu_explicit_inlining::never_inlined();
}
pub mod mod1 {
use cgu_explicit_inlining;
//~ MONO_ITEM fn mod1::user @@ inlining_from_extern_crate-mod1[External]
pub fn user()
{
cgu_explicit_inlining::inlined();
// does not generate a monomorphization in this crate
cgu_explicit_inlining::never_inlined();
}
}
pub mod mod2 {
use cgu_explicit_inlining;
//~ MONO_ITEM fn mod2::user @@ inlining_from_extern_crate-mod2[External]
pub fn user()
{
cgu_explicit_inlining::always_inlined();
// does not generate a monomorphization in this crate
cgu_explicit_inlining::never_inlined();
}
}

View file

@ -1,46 +0,0 @@
//
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// We specify opt-level=0 because `drop_in_place` is `Internal` when optimizing
// incremental
// compile-flags:-Zprint-mono-items=lazy
// compile-flags:-Zinline-in-all-cgus -Copt-level=0
#![allow(dead_code)]
#![crate_type = "rlib"]
//~ MONO_ITEM fn std::ptr::drop_in_place::<Struct> - shim(Some(Struct)) @@ local_drop_glue-fallback.cgu[External]
struct Struct {
_a: u32,
}
impl Drop for Struct {
//~ MONO_ITEM fn <Struct as std::ops::Drop>::drop @@ local_drop_glue-fallback.cgu[External]
fn drop(&mut self) {}
}
//~ MONO_ITEM fn std::ptr::drop_in_place::<Outer> - shim(Some(Outer)) @@ local_drop_glue-fallback.cgu[External]
struct Outer {
_a: Struct,
}
//~ MONO_ITEM fn user @@ local_drop_glue[External]
pub fn user() {
let _ = Outer { _a: Struct { _a: 0 } };
}
pub mod mod1 {
use super::Struct;
//~ MONO_ITEM fn std::ptr::drop_in_place::<mod1::Struct2> - shim(Some(mod1::Struct2)) @@ local_drop_glue-fallback.cgu[External]
struct Struct2 {
_a: Struct,
//~ MONO_ITEM fn std::ptr::drop_in_place::<(u32, Struct)> - shim(Some((u32, Struct))) @@ local_drop_glue-fallback.cgu[Internal]
_b: (u32, Struct),
}
//~ MONO_ITEM fn mod1::user @@ local_drop_glue-mod1[External]
pub fn user() {
let _ = Struct2 { _a: Struct { _a: 0 }, _b: (0, Struct { _a: 0 }) };
}
}

View file

@ -1,45 +0,0 @@
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// incremental
// compile-flags:-Zprint-mono-items=eager
#![allow(dead_code)]
#![crate_type="lib"]
//~ MONO_ITEM fn generic::<u32> @@ local_generic.volatile[External]
//~ MONO_ITEM fn generic::<u64> @@ local_generic.volatile[External]
//~ MONO_ITEM fn generic::<char> @@ local_generic.volatile[External]
//~ MONO_ITEM fn generic::<&str> @@ local_generic.volatile[External]
pub fn generic<T>(x: T) -> T { x }
//~ MONO_ITEM fn user @@ local_generic[Internal]
fn user() {
let _ = generic(0u32);
}
mod mod1 {
pub use super::generic;
//~ MONO_ITEM fn mod1::user @@ local_generic-mod1[Internal]
fn user() {
let _ = generic(0u64);
}
mod mod1 {
use super::generic;
//~ MONO_ITEM fn mod1::mod1::user @@ local_generic-mod1-mod1[Internal]
fn user() {
let _ = generic('c');
}
}
}
mod mod2 {
use super::generic;
//~ MONO_ITEM fn mod2::user @@ local_generic-mod2[Internal]
fn user() {
let _ = generic("abc");
}
}

View file

@ -1,45 +0,0 @@
//
// We specify incremental here because we want to test the partitioning for
// incremental compilation
// incremental
// compile-flags:-Zprint-mono-items=lazy
// compile-flags:-Zinline-in-all-cgus=no
#![allow(dead_code)]
#![crate_type="lib"]
mod inline {
//~ MONO_ITEM fn inline::inlined_function @@ local_inlining_but_not_all-inline[External]
#[inline]
pub fn inlined_function()
{
}
}
pub mod user1 {
use super::inline;
//~ MONO_ITEM fn user1::foo @@ local_inlining_but_not_all-user1[External]
pub fn foo() {
inline::inlined_function();
}
}
pub mod user2 {
use super::inline;
//~ MONO_ITEM fn user2::bar @@ local_inlining_but_not_all-user2[External]
pub fn bar() {
inline::inlined_function();
}
}
pub mod non_user {
//~ MONO_ITEM fn non_user::baz @@ local_inlining_but_not_all-non_user[External]
pub fn baz() {
}
}

Some files were not shown because too many files have changed in this diff Show more