Skip to content

tests: Add tests for LoongArch64 #110928

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 4, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions tests/codegen/abi-main-signature-16bit-c-int.rs
Original file line number Diff line number Diff line change
@@ -17,6 +17,7 @@
// ignore-wasm32
// ignore-x86
// ignore-x86_64
// ignore-loongarch64

fn main() {
}
1 change: 1 addition & 0 deletions tests/codegen/call-llvm-intrinsics.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// compile-flags: -C no-prepopulate-passes -Copt-level=0

// ignore-riscv64
// ignore-loongarch64

#![feature(link_llvm_intrinsics)]
#![crate_type = "lib"]
2 changes: 2 additions & 0 deletions tests/codegen/catch-unwind.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,8 @@
// ignore-riscv64 FIXME
// On s390x the closure is also in another function
// ignore-s390x FIXME
// On loongarch64 the closure is also in another function
// ignore-loongarch64 FIXME

#![crate_type = "lib"]
#![feature(c_unwind)]
1 change: 1 addition & 0 deletions tests/codegen/global_asm.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
// ignore-wasm32
// ignore-wasm64
// ignore-emscripten
// ignore-loongarch64
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
1 change: 1 addition & 0 deletions tests/codegen/global_asm_include.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
// ignore-wasm32
// ignore-wasm64
// ignore-emscripten
// ignore-loongarch64
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
1 change: 1 addition & 0 deletions tests/codegen/global_asm_x2.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@
// ignore-wasm32
// ignore-wasm64
// ignore-emscripten
// ignore-loongarch64
// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]
31 changes: 31 additions & 0 deletions tests/codegen/loongarch-abi/call-llvm-intrinsics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// compile-flags: -C no-prepopulate-passes

// only-loongarch64

#![feature(link_llvm_intrinsics)]
#![crate_type = "lib"]

struct A;

impl Drop for A {
fn drop(&mut self) {
println!("A");
}
}

extern "C" {
#[link_name = "llvm.sqrt.f32"]
fn sqrt(x: f32) -> f32;
}

pub fn do_call() {
let _a = A;

unsafe {
// Ensure that we `call` LLVM intrinsics instead of trying to `invoke` them
// CHECK: store float 4.000000e+00, ptr %{{.}}, align 4
// CHECK: load float, ptr %{{.}}, align 4
// CHECK: call float @llvm.sqrt.f32(float %{{.}}
sqrt(4.0);
}
}
293 changes: 293 additions & 0 deletions tests/codegen/loongarch-abi/loongarch64-lp64d-abi.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
// compile-flags: -C no-prepopulate-passes
// only-loongarch64
// only-linux

#![crate_type = "lib"]

// CHECK: define void @f_fpr_tracking(double %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, i8 noundef zeroext %i)
#[no_mangle]
pub extern "C" fn f_fpr_tracking(
a: f64,
b: f64,
c: f64,
d: f64,
e: f64,
f: f64,
g: f64,
h: f64,
i: u8,
) {
}

#[repr(C)]
pub struct Double {
f: f64,
}

#[repr(C)]
pub struct DoubleDouble {
f: f64,
g: f64,
}

#[repr(C)]
pub struct DoubleFloat {
f: f64,
g: f32,
}

// CHECK: define void @f_double_s_arg(double %0)
#[no_mangle]
pub extern "C" fn f_double_s_arg(a: Double) {}

// CHECK: define double @f_ret_double_s()
#[no_mangle]
pub extern "C" fn f_ret_double_s() -> Double {
Double { f: 1. }
}

// CHECK: define void @f_double_double_s_arg({ double, double } %0)
#[no_mangle]
pub extern "C" fn f_double_double_s_arg(a: DoubleDouble) {}

// CHECK: define { double, double } @f_ret_double_double_s()
#[no_mangle]
pub extern "C" fn f_ret_double_double_s() -> DoubleDouble {
DoubleDouble { f: 1., g: 2. }
}

// CHECK: define void @f_double_float_s_arg({ double, float } %0)
#[no_mangle]
pub extern "C" fn f_double_float_s_arg(a: DoubleFloat) {}

// CHECK: define { double, float } @f_ret_double_float_s()
#[no_mangle]
pub extern "C" fn f_ret_double_float_s() -> DoubleFloat {
DoubleFloat { f: 1., g: 2. }
}

// CHECK: define void @f_double_double_s_arg_insufficient_fprs(double %0, double %1, double %2, double %3, double %4, double %5, double %6, [2 x i64] %7)
#[no_mangle]
pub extern "C" fn f_double_double_s_arg_insufficient_fprs(
a: f64,
b: f64,
c: f64,
d: f64,
e: f64,
f: f64,
g: f64,
h: DoubleDouble,
) {
}

#[repr(C)]
pub struct DoubleInt8 {
f: f64,
i: i8,
}

#[repr(C)]
pub struct DoubleUInt8 {
f: f64,
i: u8,
}

#[repr(C)]
pub struct DoubleInt32 {
f: f64,
i: i32,
}

#[repr(C)]
pub struct DoubleInt64 {
f: f64,
i: i64,
}

// CHECK: define void @f_double_int8_s_arg({ double, i8 } %0)
#[no_mangle]
pub extern "C" fn f_double_int8_s_arg(a: DoubleInt8) {}

// CHECK: define { double, i8 } @f_ret_double_int8_s()
#[no_mangle]
pub extern "C" fn f_ret_double_int8_s() -> DoubleInt8 {
DoubleInt8 { f: 1., i: 2 }
}

// CHECK: define void @f_double_int32_s_arg({ double, i32 } %0)
#[no_mangle]
pub extern "C" fn f_double_int32_s_arg(a: DoubleInt32) {}

// CHECK: define { double, i32 } @f_ret_double_int32_s()
#[no_mangle]
pub extern "C" fn f_ret_double_int32_s() -> DoubleInt32 {
DoubleInt32 { f: 1., i: 2 }
}

// CHECK: define void @f_double_uint8_s_arg({ double, i8 } %0)
#[no_mangle]
pub extern "C" fn f_double_uint8_s_arg(a: DoubleUInt8) {}

// CHECK: define { double, i8 } @f_ret_double_uint8_s()
#[no_mangle]
pub extern "C" fn f_ret_double_uint8_s() -> DoubleUInt8 {
DoubleUInt8 { f: 1., i: 2 }
}

// CHECK: define void @f_double_int64_s_arg({ double, i64 } %0)
#[no_mangle]
pub extern "C" fn f_double_int64_s_arg(a: DoubleInt64) {}

// CHECK: define { double, i64 } @f_ret_double_int64_s()
#[no_mangle]
pub extern "C" fn f_ret_double_int64_s() -> DoubleInt64 {
DoubleInt64 { f: 1., i: 2 }
}

// CHECK: define void @f_double_int8_s_arg_insufficient_gprs(i32 noundef signext %a, i32 noundef signext %b, i32 noundef signext %c, i32 noundef signext %d, i32 noundef signext %e, i32 noundef signext %f, i32 noundef signext %g, i32 noundef signext %h, [2 x i64] %0)
#[no_mangle]
pub extern "C" fn f_double_int8_s_arg_insufficient_gprs(
a: i32,
b: i32,
c: i32,
d: i32,
e: i32,
f: i32,
g: i32,
h: i32,
i: DoubleInt8,
) {
}

// CHECK: define void @f_struct_double_int8_insufficient_fprs(float %0, double %1, double %2, double %3, double %4, double %5, double %6, double %7, [2 x i64] %8)
#[no_mangle]
pub extern "C" fn f_struct_double_int8_insufficient_fprs(
a: f32,
b: f64,
c: f64,
d: f64,
e: f64,
f: f64,
g: f64,
h: f64,
i: DoubleInt8,
) {
}

#[repr(C)]
pub struct DoubleArr1 {
a: [f64; 1],
}

// CHECK: define void @f_doublearr1_s_arg(double %0)
#[no_mangle]
pub extern "C" fn f_doublearr1_s_arg(a: DoubleArr1) {}

// CHECK: define double @f_ret_doublearr1_s()
#[no_mangle]
pub extern "C" fn f_ret_doublearr1_s() -> DoubleArr1 {
DoubleArr1 { a: [1.] }
}

#[repr(C)]
pub struct DoubleArr2 {
a: [f64; 2],
}

// CHECK: define void @f_doublearr2_s_arg({ double, double } %0)
#[no_mangle]
pub extern "C" fn f_doublearr2_s_arg(a: DoubleArr2) {}

// CHECK: define { double, double } @f_ret_doublearr2_s()
#[no_mangle]
pub extern "C" fn f_ret_doublearr2_s() -> DoubleArr2 {
DoubleArr2 { a: [1., 2.] }
}

#[repr(C)]
pub struct Tricky1 {
f: [f64; 1],
}

#[repr(C)]
pub struct DoubleArr2Tricky1 {
g: [Tricky1; 2],
}

// CHECK: define void @f_doublearr2_tricky1_s_arg({ double, double } %0)
#[no_mangle]
pub extern "C" fn f_doublearr2_tricky1_s_arg(a: DoubleArr2Tricky1) {}

// CHECK: define { double, double } @f_ret_doublearr2_tricky1_s()
#[no_mangle]
pub extern "C" fn f_ret_doublearr2_tricky1_s() -> DoubleArr2Tricky1 {
DoubleArr2Tricky1 { g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
}

#[repr(C)]
pub struct EmptyStruct {}

#[repr(C)]
pub struct DoubleArr2Tricky2 {
s: EmptyStruct,
g: [Tricky1; 2],
}

// CHECK: define void @f_doublearr2_tricky2_s_arg({ double, double } %0)
#[no_mangle]
pub extern "C" fn f_doublearr2_tricky2_s_arg(a: DoubleArr2Tricky2) {}

// CHECK: define { double, double } @f_ret_doublearr2_tricky2_s()
#[no_mangle]
pub extern "C" fn f_ret_doublearr2_tricky2_s() -> DoubleArr2Tricky2 {
DoubleArr2Tricky2 { s: EmptyStruct {}, g: [Tricky1 { f: [1.] }, Tricky1 { f: [2.] }] }
}

#[repr(C)]
pub struct IntDoubleInt {
a: i32,
b: f64,
c: i32,
}

// CHECK: define void @f_int_double_int_s_arg(ptr noalias nocapture noundef dereferenceable(24) %a)
#[no_mangle]
pub extern "C" fn f_int_double_int_s_arg(a: IntDoubleInt) {}

// CHECK: define void @f_ret_int_double_int_s(ptr noalias nocapture noundef sret(%IntDoubleInt) dereferenceable(24) %0)
#[no_mangle]
pub extern "C" fn f_ret_int_double_int_s() -> IntDoubleInt {
IntDoubleInt { a: 1, b: 2., c: 3 }
}

#[repr(C)]
pub struct CharCharDouble {
a: u8,
b: u8,
c: f64,
}

// CHECK: define void @f_char_char_double_s_arg([2 x i64] %0)
#[no_mangle]
pub extern "C" fn f_char_char_double_s_arg(a: CharCharDouble) {}

// CHECK: define [2 x i64] @f_ret_char_char_double_s()
#[no_mangle]
pub extern "C" fn f_ret_char_char_double_s() -> CharCharDouble {
CharCharDouble { a: 1, b: 2, c: 3. }
}

#[repr(C)]
pub union DoubleU {
a: f64,
}

// CHECK: define void @f_double_u_arg(i64 %0)
#[no_mangle]
pub extern "C" fn f_double_u_arg(a: DoubleU) {}

// CHECK: define i64 @f_ret_double_u()
#[no_mangle]
pub extern "C" fn f_ret_double_u() -> DoubleU {
unsafe { DoubleU { a: 1. } }
}
1 change: 1 addition & 0 deletions tests/codegen/repr-transparent-aggregates-1.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
// ignore-riscv64 see codegen/riscv-abi
// ignore-s390x
// ignore-windows
// ignore-loongarch64
// See repr-transparent.rs

#![feature(transparent_unions)]
1 change: 1 addition & 0 deletions tests/codegen/repr-transparent-aggregates-2.rs
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
// ignore-sparc64
// ignore-x86
// ignore-x86_64
// ignore-loongarch64
// See repr-transparent.rs

#![feature(transparent_unions)]
1 change: 1 addition & 0 deletions tests/codegen/repr-transparent.rs
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
// ignore-riscv64 riscv64 has an i128 type used with test_Vector
// see codegen/riscv-abi for riscv functiona call tests
// ignore-s390x s390x with default march passes vector types per reference
// ignore-loongarch64 see codegen/loongarch-abi for loongarch function call tests

#![crate_type="lib"]
#![feature(repr_simd, transparent_unions)]
1 change: 1 addition & 0 deletions tests/ui/abi/stack-probes-lto.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
// ignore-mips64
// ignore-sparc
// ignore-sparc64
// ignore-loongarch64
// ignore-wasm
// ignore-emscripten no processes
// ignore-sgx no processes
1 change: 1 addition & 0 deletions tests/ui/abi/stack-probes.rs
Original file line number Diff line number Diff line change
@@ -5,6 +5,7 @@
// ignore-mips64
// ignore-sparc
// ignore-sparc64
// ignore-loongarch64
// ignore-wasm
// ignore-emscripten no processes
// ignore-sgx no processes
3 changes: 3 additions & 0 deletions tests/ui/cfg/conditional-compile-arch.rs
Original file line number Diff line number Diff line change
@@ -39,3 +39,6 @@ pub fn main() { }

#[cfg(target_arch = "riscv64")]
pub fn main() { }

#[cfg(target_arch = "loongarch64")]
pub fn main() { }
1 change: 1 addition & 0 deletions tests/ui/target-feature/gate.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
// ignore-sparc
// ignore-sparc64
// ignore-s390x
// ignore-loongarch64
// gate-test-sse4a_target_feature
// gate-test-powerpc_target_feature
// gate-test-avx512_target_feature
2 changes: 1 addition & 1 deletion tests/ui/target-feature/gate.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0658]: the target feature `avx512bw` is currently unstable
--> $DIR/gate.rs:31:18
--> $DIR/gate.rs:32:18
|
LL | #[target_feature(enable = "avx512bw")]
| ^^^^^^^^^^^^^^^^^^^
1 change: 1 addition & 0 deletions tests/ui/target-feature/invalid-attribute.rs
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
// ignore-s390x
// ignore-sparc
// ignore-sparc64
// ignore-loongarch64

#![warn(unused_attributes)]

44 changes: 22 additions & 22 deletions tests/ui/target-feature/invalid-attribute.stderr
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
error: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:31:1
--> $DIR/invalid-attribute.rs:32:1
|
LL | #[target_feature = "+sse2"]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[target_feature(enable = "name")]`

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:16:1
--> $DIR/invalid-attribute.rs:17:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -14,7 +14,7 @@ LL | extern crate alloc;
| ------------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:21:1
--> $DIR/invalid-attribute.rs:22:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -23,7 +23,7 @@ LL | use alloc::alloc::alloc;
| ------------------------ not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:26:1
--> $DIR/invalid-attribute.rs:27:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL | extern "Rust" {}
| ---------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:48:1
--> $DIR/invalid-attribute.rs:49:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL | mod another {}
| -------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:53:1
--> $DIR/invalid-attribute.rs:54:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -50,7 +50,7 @@ LL | const FOO: usize = 7;
| --------------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:58:1
--> $DIR/invalid-attribute.rs:59:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -59,7 +59,7 @@ LL | struct Foo;
| ----------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:63:1
--> $DIR/invalid-attribute.rs:64:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,7 +68,7 @@ LL | enum Bar {}
| ----------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:68:1
--> $DIR/invalid-attribute.rs:69:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL | | }
| |_- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:76:1
--> $DIR/invalid-attribute.rs:77:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL | type Uwu = ();
| -------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:81:1
--> $DIR/invalid-attribute.rs:82:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL | trait Baz {}
| ------------ not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:91:1
--> $DIR/invalid-attribute.rs:92:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL | static A: () = ();
| ------------------ not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:96:1
--> $DIR/invalid-attribute.rs:97:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL | impl Quux for u8 {}
| ------------------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:101:1
--> $DIR/invalid-attribute.rs:102:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL | impl Foo {}
| ----------- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:119:5
--> $DIR/invalid-attribute.rs:120:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -138,7 +138,7 @@ LL | | }
| |_____- not a function definition

error: attribute should be applied to a function definition
--> $DIR/invalid-attribute.rs:127:5
--> $DIR/invalid-attribute.rs:128:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -147,25 +147,25 @@ LL | || {};
| ----- not a function definition

error: the feature named `foo` is not valid for this target
--> $DIR/invalid-attribute.rs:33:18
--> $DIR/invalid-attribute.rs:34:18
|
LL | #[target_feature(enable = "foo")]
| ^^^^^^^^^^^^^^ `foo` is not valid for this target

error: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:36:18
--> $DIR/invalid-attribute.rs:37:18
|
LL | #[target_feature(bar)]
| ^^^ help: must be of the form: `enable = ".."`

error: malformed `target_feature` attribute input
--> $DIR/invalid-attribute.rs:38:18
--> $DIR/invalid-attribute.rs:39:18
|
LL | #[target_feature(disable = "baz")]
| ^^^^^^^^^^^^^^^ help: must be of the form: `enable = ".."`

error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/invalid-attribute.rs:42:1
--> $DIR/invalid-attribute.rs:43:1
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,13 +177,13 @@ LL | fn bar() {}
= help: add `#![feature(target_feature_11)]` to the crate attributes to enable

error: cannot use `#[inline(always)]` with `#[target_feature]`
--> $DIR/invalid-attribute.rs:86:1
--> $DIR/invalid-attribute.rs:87:1
|
LL | #[inline(always)]
| ^^^^^^^^^^^^^^^^^

error[E0658]: `#[target_feature(..)]` can only be applied to `unsafe` functions
--> $DIR/invalid-attribute.rs:111:5
--> $DIR/invalid-attribute.rs:112:5
|
LL | #[target_feature(enable = "sse2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^