-
Notifications
You must be signed in to change notification settings - Fork 13k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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`
- Loading branch information
Showing
3 changed files
with
110 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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() }; | ||
} |