diff options
| author | bors <bors@rust-lang.org> | 2025-01-17 15:07:28 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-01-17 15:07:28 +0000 |
| commit | bcd0683e5dce1945b5d940714742e7502883bb5c (patch) | |
| tree | e568849b86bdfc2862ddecd39be68f4c3f2995d9 /tests/codegen | |
| parent | 73c0ae6aec8f3d07467dfb9339761fa2eec92a44 (diff) | |
| parent | 702134a9300dd36b8c49a044a06d4bc8e454cf87 (diff) | |
| download | rust-bcd0683e5dce1945b5d940714742e7502883bb5c.tar.gz rust-bcd0683e5dce1945b5d940714742e7502883bb5c.zip | |
Auto merge of #135534 - folkertdev:fix-wasm-i128-f128, r=tgross35
use indirect return for `i128` and `f128` on wasm32 fixes #135532 Based on https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md we now use an indirect return for `i128`, `u128` and `f128`. That is what LLVM ended up doing anyway. r? `@bjorn3`
Diffstat (limited to 'tests/codegen')
| -rw-r--r-- | tests/codegen/f128-wasm32-callconv.rs | 49 | ||||
| -rw-r--r-- | tests/codegen/i128-wasm32-callconv.rs | 49 |
2 files changed, 98 insertions, 0 deletions
diff --git a/tests/codegen/f128-wasm32-callconv.rs b/tests/codegen/f128-wasm32-callconv.rs new file mode 100644 index 00000000000..8b1b5e7fb01 --- /dev/null +++ b/tests/codegen/f128-wasm32-callconv.rs @@ -0,0 +1,49 @@ +//! Verify that Rust implements the expected calling convention for `f128` + +//@ add-core-stubs +//@ compile-flags: -O --target wasm32-wasip1 +//@ needs-llvm-components: webassembly + +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![feature(no_core, lang_items, f128)] + +extern crate minicore; + +extern "C" { + fn extern_call(arg0: f128); + fn extern_ret() -> f128; +} + +#[no_mangle] +pub extern "C" fn pass(_arg0: u32, arg1: f128) { + // CHECK-LABEL: @pass( + // an f128 is passed via registers + // CHECK-SAME: fp128 noundef %arg1 + // CHECK: call void @extern_call + unsafe { extern_call(arg1) }; +} + +// Check that we produce the correct return ABI +#[no_mangle] +pub extern "C" fn ret(_arg0: u32, arg1: f128) -> f128 { + // CHECK-LABEL: @ret( + // but an f128 is returned via the stack + // CHECK-SAME: sret + // CHECK: store fp128 %arg1 + // CHECK-NEXT: ret void + arg1 +} + +// Check that we consume the correct return ABI +#[no_mangle] +pub extern "C" fn forward(dst: *mut f128) { + // CHECK-LABEL: @forward + // CHECK-SAME: ptr{{.*}} %dst) + // without optimizatons, an intermediate alloca is used + // CHECK: call void @extern_ret + // CHECK: store fp128 + // CHECK: ret void + unsafe { *dst = extern_ret() }; +} diff --git a/tests/codegen/i128-wasm32-callconv.rs b/tests/codegen/i128-wasm32-callconv.rs new file mode 100644 index 00000000000..c6d25fbe8be --- /dev/null +++ b/tests/codegen/i128-wasm32-callconv.rs @@ -0,0 +1,49 @@ +//! Verify that Rust implements the expected calling convention for `i128`/`u128`. + +//@ add-core-stubs +//@ compile-flags: -O --target wasm32-wasip1 +//@ needs-llvm-components: webassembly + +#![crate_type = "lib"] +#![no_std] +#![no_core] +#![feature(no_core, lang_items)] + +extern crate minicore; + +extern "C" { + fn extern_call(arg0: i128); + fn extern_ret() -> i128; +} + +#[no_mangle] +pub extern "C" fn pass(_arg0: u32, arg1: i128) { + // CHECK-LABEL: @pass( + // an i128 is passed via registers + // CHECK-SAME: i128 noundef %arg1 + // CHECK: call void @extern_call + unsafe { extern_call(arg1) }; +} + +// Check that we produce the correct return ABI +#[no_mangle] +pub extern "C" fn ret(_arg0: u32, arg1: i128) -> i128 { + // CHECK-LABEL: @ret( + // but an i128 is returned via the stack + // CHECK-SAME: sret + // CHECK: store i128 %arg1 + // CHECK-NEXT: ret void + arg1 +} + +// Check that we consume the correct return ABI +#[no_mangle] +pub extern "C" fn forward(dst: *mut i128) { + // CHECK-LABEL: @forward + // CHECK-SAME: ptr{{.*}} %dst) + // without optimizatons, an intermediate alloca is used + // CHECK: call void @extern_ret + // CHECK: store i128 + // CHECK: ret void + unsafe { *dst = extern_ret() }; +} |
