From 5b66cc1ab24491e50fbc7be04b21e00ca6a8f41f Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Sat, 4 Jul 2026 20:30:00 +0200 Subject: [PATCH 1/8] add `Complex` type --- compiler/rustc_attr_ir/src/lang_items.rs | 2 ++ compiler/rustc_span/src/symbol.rs | 1 + library/core/src/num/complex.rs | 20 ++++++++++++++++++++ library/core/src/num/mod.rs | 3 +++ library/std/src/num/mod.rs | 2 ++ tests/auxiliary/minicore.rs | 13 +++++++++++++ 6 files changed, 41 insertions(+) create mode 100644 library/core/src/num/complex.rs diff --git a/compiler/rustc_attr_ir/src/lang_items.rs b/compiler/rustc_attr_ir/src/lang_items.rs index 34f4fba5b0eea..e45621689558e 100644 --- a/compiler/rustc_attr_ir/src/lang_items.rs +++ b/compiler/rustc_attr_ir/src/lang_items.rs @@ -232,6 +232,8 @@ language_item_table! { VaArgSafe, sym::va_arg_safe, va_arg_safe, Target::Trait, GenericRequirement::None; VaList, sym::va_list, va_list, Target::Struct, GenericRequirement::None; + Complex, sym::complex, complex, Target::Struct, GenericRequirement::Exact(1); + Deref, sym::deref, deref_trait, Target::Trait, GenericRequirement::Exact(0); DerefMut, sym::deref_mut, deref_mut_trait, Target::Trait, GenericRequirement::Exact(0); DerefPure, sym::deref_pure, deref_pure_trait, Target::Trait, GenericRequirement::Exact(0); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 85f0ce7e6af00..d045f2ab3801b 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -654,6 +654,7 @@ symbols! { compiler_copy, compiler_fence, compiler_move, + complex, concat, concat_bytes, conservative_impl_trait, diff --git a/library/core/src/num/complex.rs b/library/core/src/num/complex.rs new file mode 100644 index 0000000000000..9321718899cdd --- /dev/null +++ b/library/core/src/num/complex.rs @@ -0,0 +1,20 @@ +/// A complex number. +#[derive(Clone, Copy, Debug, PartialEq)] +#[unstable(feature = "complex_numbers", issue = "154023")] +#[repr(C)] +#[lang = "complex"] +pub struct Complex { + /// The real component. + pub re: T, + /// The imaginary component. + pub im: T, +} + +#[unstable(feature = "complex_numbers", issue = "154023")] +impl Complex { + /// Create a new complex number from a real and imaginary component. + #[must_use] + pub fn new(re: T, im: T) -> Complex { + Complex { re, im } + } +} diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs index 478af470637d7..793222538ba41 100644 --- a/library/core/src/num/mod.rs +++ b/library/core/src/num/mod.rs @@ -42,6 +42,7 @@ mod int_macros; // import int_impl! #[macro_use] mod uint_macros; // import uint_impl! +mod complex; mod error; #[cfg(not(no_fp_fmt_parse))] mod float_parse; @@ -54,6 +55,8 @@ mod wrapping; #[doc(hidden)] pub mod niche_types; +#[unstable(feature = "complex_numbers", issue = "154023")] +pub use complex::Complex; #[stable(feature = "int_error_matching", since = "1.55.0")] pub use error::IntErrorKind; #[stable(feature = "rust1", since = "1.0.0")] diff --git a/library/std/src/num/mod.rs b/library/std/src/num/mod.rs index ffb8789c906ef..5aa6c1492ec65 100644 --- a/library/std/src/num/mod.rs +++ b/library/std/src/num/mod.rs @@ -6,6 +6,8 @@ #![stable(feature = "rust1", since = "1.0.0")] #![allow(missing_docs)] +#[unstable(feature = "complex_numbers", issue = "154023")] +pub use core::num::Complex; #[stable(feature = "int_error_matching", since = "1.55.0")] pub use core::num::IntErrorKind; #[stable(feature = "generic_nonzero", since = "1.79.0")] diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs index e8bfdf80c98e8..b732088553bb3 100644 --- a/tests/auxiliary/minicore.rs +++ b/tests/auxiliary/minicore.rs @@ -391,6 +391,19 @@ pub mod hint { } } +pub mod num { + use super::Copy; + + #[repr(C)] + #[lang = "complex"] + pub struct Complex { + pub re: T, + pub im: T, + } + + impl Copy for Complex {} +} + #[lang = "c_void"] #[repr(u8)] pub enum c_void { From d7ec10329604304dfaf8b9f7a436d983f6db5176 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Aug 2026 22:53:03 +0200 Subject: [PATCH 2/8] update hygiene test the new `sym::complex` in the previous commit pushes some symbol from 999 to 1000, which causes the formatting change here --- tests/ui/hygiene/unpretty-debug-lifetimes.stdout | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout index 689453326c0b5..c75cc7b2179d3 100644 --- a/tests/ui/hygiene/unpretty-debug-lifetimes.stdout +++ b/tests/ui/hygiene/unpretty-debug-lifetimes.stdout @@ -15,8 +15,8 @@ macro lifetime_hygiene /* 0#0 */ { - ($f /* 0#0 */:ident /* 0#0 */<$a /* 0#0 */:lifetime /* 0#0 */>) - => + ($f /* 0#0 */:ident /* 0#0 */<$a /* 0#0 */:lifetime /* 0#0 + */>) => { fn /* 0#0 */ $f /* 0#0 */<$a /* 0#0 */, 'a /* 0#0 */>() {} } } fn f /* 0#0 */<'a /* 0#0 */, 'a /* 0#1 */>() {} From 592e1384d427d33246b4f1de630543725d51dd8a Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 12 Aug 2026 15:33:31 +0200 Subject: [PATCH 3/8] define `Ty::is_complex` --- compiler/rustc_abi/src/layout/ty.rs | 8 ++++++++ compiler/rustc_middle/src/ty/layout.rs | 14 ++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 11aa18cdb224d..06bcb2b132597 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -120,6 +120,7 @@ pub trait TyAbiInterface<'a, C>: Sized + std::fmt::Debug + std::fmt::Display { fn is_tuple(this: TyAndLayout<'a, Self>) -> bool; fn is_unit(this: TyAndLayout<'a, Self>) -> bool; fn is_transparent(this: TyAndLayout<'a, Self>) -> bool; + fn is_complex_number(this: TyAndLayout<'a, Self>, cx: &C) -> bool; fn is_scalable_vector(this: TyAndLayout<'a, Self>) -> bool; /// See [`TyAndLayout::pass_indirectly_in_non_rustic_abis`] for details. fn is_pass_indirectly_in_non_rustic_abis_flag_set(this: TyAndLayout<'a, Self>) -> bool; @@ -227,6 +228,13 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { Ty::is_transparent(self) } + pub fn is_complex_number(self, cx: &C) -> bool + where + Ty: TyAbiInterface<'a, C> + Copy, + { + Ty::is_complex_number(self.peel_transparent_wrappers(cx), cx) + } + pub fn is_scalable_vector(self) -> bool where Ty: TyAbiInterface<'a, C>, diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 562a40f182312..af2481f47c9ba 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -1213,6 +1213,20 @@ where matches!(this.ty.kind(), ty::Adt(def, _) if def.repr().transparent()) } + /// Does this type have a layout compatible with C `_Complex`? + /// + /// The value must be of type `core::num::Complex` where `T` is numeric. + fn is_complex_number(this: TyAndLayout<'tcx>, cx: &C) -> bool { + let ty::Adt(def, generic_args) = this.ty.kind() else { return false }; + + if !cx.tcx().is_lang_item(def.did(), LangItem::Complex) { + return false; + } + + // Only Complex<{ float }> and Complex<{ integer }> have special layout. + generic_args.type_at(0).is_numeric() + } + fn is_scalable_vector(this: TyAndLayout<'tcx>) -> bool { this.ty.is_scalable_vector() } From 3512f08ab346031bcbe37905aa038c1d12cd0296 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 22:55:47 +0200 Subject: [PATCH 4/8] add `complex-abi.rs` test --- tests/codegen-llvm/complex-abi.rs | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 tests/codegen-llvm/complex-abi.rs diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs new file mode 100644 index 0000000000000..d7763ee4deb18 --- /dev/null +++ b/tests/codegen-llvm/complex-abi.rs @@ -0,0 +1,69 @@ +//! Checks that `#[repr(complex)]` `Complex` matches the C `_Complex` ABI in `extern "C"` +//! functions. This is the rustc side of `tests/run-make/complex-c-abi`, which additionally +//! checks these signatures against clang. Revisions are grouped by LLVM component. + +//@ add-minicore +//@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order -C opt-level=3 + +#![feature(no_core, lang_items, repr_complex, f16, f128)] +#![no_core] +#![allow(improper_ctypes)] // only Complex<{float}> is guaranteed to be ABI-compatible for now +#![crate_type = "lib"] + +extern crate minicore; +use minicore::num::Complex; + +#[no_mangle] +pub extern "C" fn cplx_f16(x: Complex) -> Complex { + // CHECK: cplx_f16 + x +} + +#[no_mangle] +pub extern "C" fn cplx_f32(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_f64(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_f128(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i8(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i16(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i32(x: Complex) -> Complex { + x +} + +#[no_mangle] +pub extern "C" fn cplx_i64(x: Complex) -> Complex { + x +} + +#[repr(transparent)] +struct Wrapper(T); + +#[no_mangle] +pub extern "C" fn wrapper_cplx_i64(x: Wrapper>) -> Wrapper> { + // I686: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_GNU: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @wrapper_cplx_i64({ i64, i64 } {{.*}}) + x +} From 3238bbfdaf4206241cf2fa2110eb1a393b147ed5 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:21:20 +0200 Subject: [PATCH 5/8] add CHECK lines and revisions --- tests/codegen-llvm/complex-abi.rs | 284 +++++++++++++++++++++++++++++- 1 file changed, 282 insertions(+), 2 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index d7763ee4deb18..ddb0065b901c7 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -5,7 +5,91 @@ //@ add-minicore //@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order -C opt-level=3 -#![feature(no_core, lang_items, repr_complex, f16, f128)] +//@ revisions: X86_64 I686 WINDOWS_MSVC WINDOWS_GNU WIN32_MSVC WIN32_GNU +//@ [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 +//@ [WINDOWS_MSVC] compile-flags: --target x86_64-pc-windows-msvc +//@ [WINDOWS_MSVC] needs-llvm-components: x86 +//@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu +//@ [WINDOWS_GNU] needs-llvm-components: x86 +//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +//@ [WIN32_MSVC] needs-llvm-components: x86 +//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +//@ [WIN32_GNU] needs-llvm-components: x86 + +//@ revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC +//@ [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu +//@ [AARCH64] needs-llvm-components: aarch64 +//@ [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin +//@ [AARCH64_DARWIN] needs-llvm-components: aarch64 +//@ [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc +//@ [AARCH64_MSVC] needs-llvm-components: aarch64 +//@ [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc +//@ [ARM64EC] needs-llvm-components: aarch64 + +//@ revisions: ARM +//@ [ARM] compile-flags: --target arm-unknown-linux-gnueabihf +//@ [ARM] needs-llvm-components: arm + +//@ revisions: RISCV64 RISCV32 +//@ [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu +//@ [RISCV64] needs-llvm-components: riscv +//@ [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu +//@ [RISCV32] needs-llvm-components: riscv + +//@ revisions: LOONGARCH64 LOONGARCH32 +//@ [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu +//@ [LOONGARCH64] needs-llvm-components: loongarch +//@ [LOONGARCH32] compile-flags: --target loongarch32-unknown-none +//@ [LOONGARCH32] needs-llvm-components: loongarch + +//@ revisions: SPARC64 SPARC +//@ [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu +//@ [SPARC64] needs-llvm-components: sparc +//@ [SPARC] compile-flags: --target sparc-unknown-linux-gnu +//@ [SPARC] needs-llvm-components: sparc + +//@ revisions: S390X +//@ [S390X] compile-flags: --target s390x-unknown-linux-gnu +//@ [S390X] needs-llvm-components: systemz + +//@ revisions: POWERPC POWERPC64LE POWERPC64 AIX +//@ [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu +//@ [POWERPC] needs-llvm-components: powerpc +//@ [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu +//@ [POWERPC64LE] needs-llvm-components: powerpc +//@ [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu +//@ [POWERPC64] needs-llvm-components: powerpc +//@ [AIX] compile-flags: --target powerpc64-ibm-aix +//@ [AIX] needs-llvm-components: powerpc + +//@ revisions: MIPS64EL MIPS +//@ [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 +//@ [MIPS64EL] needs-llvm-components: mips +//@ [MIPS] compile-flags: --target mips-unknown-linux-gnu +//@ [MIPS] needs-llvm-components: mips + +//@ revisions: WASM32 WASM64 +//@ [WASM32] compile-flags: --target wasm32-unknown-unknown +//@ [WASM32] needs-llvm-components: webassembly +//@ [WASM64] compile-flags: --target wasm64-unknown-unknown +//@ [WASM64] needs-llvm-components: webassembly + +//@ revisions: CSKY +//@ [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 +//@ [CSKY] needs-llvm-components: csky + +//@ revisions: NVPTX +//@ [NVPTX] compile-flags: --target nvptx64-nvidia-cuda +//@ [NVPTX] needs-llvm-components: nvptx + +//@ revisions: BPF +//@ [BPF] compile-flags: --target bpfel-unknown-none +//@ [BPF] needs-llvm-components: bpf + +#![feature(no_core, lang_items, f16, f128)] #![no_core] #![allow(improper_ctypes)] // only Complex<{float}> is guaranteed to be ABI-compatible for now #![crate_type = "lib"] @@ -15,42 +99,238 @@ use minicore::num::Complex; #[no_mangle] pub extern "C" fn cplx_f16(x: Complex) -> Complex { - // CHECK: cplx_f16 + // AARCH64: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // AARCH64_MSVC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // ARM64EC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) + // ARM: define{{.*}} i32 @cplx_f16([1 x i32] {{.*}}) + // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // LOONGARCH32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // LOONGARCH64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // NVPTX: define{{.*}} { half, half } @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // RISCV32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // RISCV64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) + // S390X: define{{.*}} void @cplx_f16(ptr {{.*}} sret({ half, half }) {{.*}}, ptr {{.*}}) + // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) + // X86_64: define{{.*}} <2 x half> @cplx_f16(<2 x half> {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f32(x: Complex) -> Complex { + // AARCH64: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AARCH64_MSVC: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // AIX: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // ARM64EC: define{{.*}} { float, float } @cplx_f32([2 x float] {{.*}}) + // ARM: define{{.*}} { float, float } @cplx_f32({ float, float } {{.*}}) + // BPF: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, i64 {{.*}}) + // CSKY: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}}) + // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // LOONGARCH32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // LOONGARCH64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // MIPS64EL: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // MIPS: define{{.*}} { float, float } @cplx_f32(i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // POWERPC64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // POWERPC64LE: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // POWERPC: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // RISCV32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // RISCV64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // S390X: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) + // SPARC: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) + // X86_64: define{{.*}} <2 x float> @cplx_f32(<2 x float> {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f64(x: Complex) -> Complex { + // AARCH64: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AARCH64_DARWIN: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AARCH64_MSVC: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // AIX: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // ARM64EC: define{{.*}} { double, double } @cplx_f64([2 x double] {{.*}}) + // ARM: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) + // BPF: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [2 x i64] {{.*}}) + // CSKY: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [4 x i32] {{.*}}) + // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // LOONGARCH32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // LOONGARCH64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // MIPS64EL: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // MIPS: define{{.*}} { double, double } @cplx_f64(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) + // POWERPC64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // POWERPC64LE: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // POWERPC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // RISCV32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // RISCV64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // S390X: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // SPARC: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_f128(x: Complex) -> Complex { + // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i8(x: Complex) -> Complex { + // AARCH64: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AARCH64_DARWIN: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AARCH64_MSVC: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // AIX: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // ARM64EC: define{{.*}} i16 @cplx_i8(i64{{.*}}) + // ARM: define{{.*}} i16 @cplx_i8([1 x i32]{{.*}}) + // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) + // CSKY: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // LOONGARCH32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // MIPS64EL: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) + // MIPS: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) + // NVPTX: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // POWERPC64: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // POWERPC64LE: define{{.*}} { i8, i8 } @cplx_i8(i8 {{.*}}, i8 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // RISCV32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) + // RISCV64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // S390X: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) + // SPARC: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i16 @cplx_i8(i16 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i16 @cplx_i8(i16 {{.*}}) + // X86_64: define{{.*}} i16 @cplx_i8(i16 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i16(x: Complex) -> Complex { + // AARCH64: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AARCH64_DARWIN: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AARCH64_MSVC: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // AIX: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // ARM64EC: define{{.*}} i32 @cplx_i16(i64{{.*}}) + // ARM: define{{.*}} i32 @cplx_i16([1 x i32] {{.*}}) + // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) + // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // LOONGARCH32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // MIPS64EL: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) + // MIPS: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) + // NVPTX: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // POWERPC64: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // POWERPC64LE: define{{.*}} { i16, i16 } @cplx_i16(i16 {{.*}}, i16 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // RISCV32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // RISCV64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // S390X: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) + // SPARC: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // X86_64: define{{.*}} i32 @cplx_i16(i32 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i32(x: Complex) -> Complex { + // AARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AARCH64_DARWIN: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AARCH64_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // AIX: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // ARM64EC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // ARM: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, [2 x i32] {{.*}}) + // BPF: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, i64 {{.*}}) + // CSKY: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // LOONGARCH32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // LOONGARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // MIPS64EL: define{{.*}} { i32, i32 } @cplx_i32(i64 {{.*}}) + // MIPS: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // POWERPC64: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // POWERPC64LE: define{{.*}} { i32, i32 } @cplx_i32(i32 {{.*}}, i32 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // RISCV32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // RISCV64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // S390X: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // SPARC: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // WINDOWS_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) + // X86_64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) x } #[no_mangle] pub extern "C" fn cplx_i64(x: Complex) -> Complex { + // AARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AARCH64_DARWIN: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AARCH64_MSVC: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // AIX: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // ARM64EC: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // ARM: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) + // BPF: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) + // CSKY: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [4 x i32] {{.*}}) + // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // LOONGARCH32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // LOONGARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // MIPS64EL: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // MIPS: define{{.*}} { i64, i64 } @cplx_i64(i32 {{.*}}, i32 {{.*}}, i32 {{.*}}, i32 {{.*}}) + // NVPTX: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // POWERPC64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // POWERPC64LE: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // POWERPC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // RISCV32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // RISCV64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) + // S390X: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // SPARC64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // SPARC: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WASM32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) x } From 256743423793e7dbfc38736ca0c529b13176cb30 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:25:14 +0200 Subject: [PATCH 6/8] disable most revisions --- tests/codegen-llvm/complex-abi.rs | 134 +++++++++++++++--------------- 1 file changed, 69 insertions(+), 65 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index ddb0065b901c7..9b9c71f7e6116 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -5,89 +5,93 @@ //@ add-minicore //@ compile-flags: -C no-prepopulate-passes -Z codegen-source-order -C opt-level=3 -//@ revisions: X86_64 I686 WINDOWS_MSVC WINDOWS_GNU WIN32_MSVC WIN32_GNU +//@ revisions: X86_64 WINDOWS_MSVC WINDOWS_GNU //@ [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 //@ [WINDOWS_MSVC] compile-flags: --target x86_64-pc-windows-msvc //@ [WINDOWS_MSVC] needs-llvm-components: x86 //@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu //@ [WINDOWS_GNU] needs-llvm-components: x86 -//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc -//@ [WIN32_MSVC] needs-llvm-components: x86 -//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu -//@ [WIN32_GNU] needs-llvm-components: x86 -//@ revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC -//@ [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu -//@ [AARCH64] needs-llvm-components: aarch64 -//@ [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin -//@ [AARCH64_DARWIN] needs-llvm-components: aarch64 -//@ [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc -//@ [AARCH64_MSVC] needs-llvm-components: aarch64 -//@ [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc -//@ [ARM64EC] needs-llvm-components: aarch64 +// FIXME: the below revisions are deliberately disabled for now. -//@ revisions: ARM -//@ [ARM] compile-flags: --target arm-unknown-linux-gnueabihf -//@ [ARM] needs-llvm-components: arm +// revisions: I686 WIN32_MSVC WIN32_GNU +// [I686] compile-flags: --target i686-unknown-linux-gnu +// [I686] needs-llvm-components: x86 +// [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +// [WIN32_MSVC] needs-llvm-components: x86 +// [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +// [WIN32_GNU] needs-llvm-components: x86 -//@ revisions: RISCV64 RISCV32 -//@ [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu -//@ [RISCV64] needs-llvm-components: riscv -//@ [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu -//@ [RISCV32] needs-llvm-components: riscv +// revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC +// [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu +// [AARCH64] needs-llvm-components: aarch64 +// [AARCH64_DARWIN] compile-flags: --target aarch64-apple-darwin +// [AARCH64_DARWIN] needs-llvm-components: aarch64 +// [AARCH64_MSVC] compile-flags: --target aarch64-pc-windows-msvc +// [AARCH64_MSVC] needs-llvm-components: aarch64 +// [ARM64EC] compile-flags: --target arm64ec-pc-windows-msvc +// [ARM64EC] needs-llvm-components: aarch64 -//@ revisions: LOONGARCH64 LOONGARCH32 -//@ [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu -//@ [LOONGARCH64] needs-llvm-components: loongarch -//@ [LOONGARCH32] compile-flags: --target loongarch32-unknown-none -//@ [LOONGARCH32] needs-llvm-components: loongarch +// revisions: ARM +// [ARM] compile-flags: --target arm-unknown-linux-gnueabihf +// [ARM] needs-llvm-components: arm -//@ revisions: SPARC64 SPARC -//@ [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu -//@ [SPARC64] needs-llvm-components: sparc -//@ [SPARC] compile-flags: --target sparc-unknown-linux-gnu -//@ [SPARC] needs-llvm-components: sparc +// revisions: RISCV64 RISCV32 +// [RISCV64] compile-flags: --target riscv64gc-unknown-linux-gnu +// [RISCV64] needs-llvm-components: riscv +// [RISCV32] compile-flags: --target riscv32gc-unknown-linux-gnu +// [RISCV32] needs-llvm-components: riscv -//@ revisions: S390X -//@ [S390X] compile-flags: --target s390x-unknown-linux-gnu -//@ [S390X] needs-llvm-components: systemz +// revisions: LOONGARCH64 LOONGARCH32 +// [LOONGARCH64] compile-flags: --target loongarch64-unknown-linux-gnu +// [LOONGARCH64] needs-llvm-components: loongarch +// [LOONGARCH32] compile-flags: --target loongarch32-unknown-none +// [LOONGARCH32] needs-llvm-components: loongarch -//@ revisions: POWERPC POWERPC64LE POWERPC64 AIX -//@ [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu -//@ [POWERPC] needs-llvm-components: powerpc -//@ [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu -//@ [POWERPC64LE] needs-llvm-components: powerpc -//@ [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu -//@ [POWERPC64] needs-llvm-components: powerpc -//@ [AIX] compile-flags: --target powerpc64-ibm-aix -//@ [AIX] needs-llvm-components: powerpc +// revisions: SPARC64 SPARC +// [SPARC64] compile-flags: --target sparc64-unknown-linux-gnu +// [SPARC64] needs-llvm-components: sparc +// [SPARC] compile-flags: --target sparc-unknown-linux-gnu +// [SPARC] needs-llvm-components: sparc -//@ revisions: MIPS64EL MIPS -//@ [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 -//@ [MIPS64EL] needs-llvm-components: mips -//@ [MIPS] compile-flags: --target mips-unknown-linux-gnu -//@ [MIPS] needs-llvm-components: mips +// revisions: S390X +// [S390X] compile-flags: --target s390x-unknown-linux-gnu +// [S390X] needs-llvm-components: systemz -//@ revisions: WASM32 WASM64 -//@ [WASM32] compile-flags: --target wasm32-unknown-unknown -//@ [WASM32] needs-llvm-components: webassembly -//@ [WASM64] compile-flags: --target wasm64-unknown-unknown -//@ [WASM64] needs-llvm-components: webassembly +// revisions: POWERPC POWERPC64LE POWERPC64 AIX +// [POWERPC] compile-flags: --target powerpc-unknown-linux-gnu +// [POWERPC] needs-llvm-components: powerpc +// [POWERPC64LE] compile-flags: --target powerpc64le-unknown-linux-gnu +// [POWERPC64LE] needs-llvm-components: powerpc +// [POWERPC64] compile-flags: --target powerpc64-unknown-linux-gnu +// [POWERPC64] needs-llvm-components: powerpc +// [AIX] compile-flags: --target powerpc64-ibm-aix +// [AIX] needs-llvm-components: powerpc -//@ revisions: CSKY -//@ [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 -//@ [CSKY] needs-llvm-components: csky +// revisions: MIPS64EL MIPS +// [MIPS64EL] compile-flags: --target mips64el-unknown-linux-gnuabi64 +// [MIPS64EL] needs-llvm-components: mips +// [MIPS] compile-flags: --target mips-unknown-linux-gnu +// [MIPS] needs-llvm-components: mips -//@ revisions: NVPTX -//@ [NVPTX] compile-flags: --target nvptx64-nvidia-cuda -//@ [NVPTX] needs-llvm-components: nvptx +// revisions: WASM32 WASM64 +// [WASM32] compile-flags: --target wasm32-unknown-unknown +// [WASM32] needs-llvm-components: webassembly +// [WASM64] compile-flags: --target wasm64-unknown-unknown +// [WASM64] needs-llvm-components: webassembly -//@ revisions: BPF -//@ [BPF] compile-flags: --target bpfel-unknown-none -//@ [BPF] needs-llvm-components: bpf +// revisions: CSKY +// [CSKY] compile-flags: --target csky-unknown-linux-gnuabiv2 +// [CSKY] needs-llvm-components: csky + +// revisions: NVPTX +// [NVPTX] compile-flags: --target nvptx64-nvidia-cuda +// [NVPTX] needs-llvm-components: nvptx + +// revisions: BPF +// [BPF] compile-flags: --target bpfel-unknown-none +// [BPF] needs-llvm-components: bpf #![feature(no_core, lang_items, f16, f128)] #![no_core] From 130ae0bd0087a46e4dfe40329a3a808d6063dcd1 Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Mon, 6 Jul 2026 23:41:57 +0200 Subject: [PATCH 7/8] Implement and test x86_64 Complex --- tests/codegen-llvm/complex-abi.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index 9b9c71f7e6116..5c58eae7a5bb4 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -119,7 +119,7 @@ pub extern "C" fn cplx_f16(x: Complex) -> Complex { // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) - // X86_64: define{{.*}} <2 x half> @cplx_f16(<2 x half> {{.*}}) + // X86_64: define{{.*}} float @cplx_f16(float {{.*}}) x } @@ -153,7 +153,7 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) - // X86_64: define{{.*}} <2 x float> @cplx_f32(<2 x float> {{.*}}) + // X86_64: define{{.*}} double @cplx_f32(double {{.*}}) x } @@ -185,9 +185,9 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) - // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) x } @@ -197,8 +197,8 @@ pub extern "C" fn cplx_f128(x: Complex) -> Complex { // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) x } @@ -332,9 +332,9 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) - // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) - // X86_64: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) + // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) + // X86_64: define{{.*}} { i64, i64 } @cplx_i64({ i64, i64 } {{.*}}) x } From 534309dd12d210a666d942b035bec4d87882c4ad Mon Sep 17 00:00:00 2001 From: Folkert de Vries Date: Wed, 22 Jul 2026 01:26:49 +0200 Subject: [PATCH 8/8] `Complex` return on `x86` --- compiler/rustc_abi/src/layout/ty.rs | 20 ++++++ compiler/rustc_target/src/callconv/x86.rs | 11 +++- .../rustc_target/src/callconv/x86_win32.rs | 8 ++- tests/codegen-llvm/complex-abi.rs | 62 +++++++++---------- 4 files changed, 66 insertions(+), 35 deletions(-) diff --git a/compiler/rustc_abi/src/layout/ty.rs b/compiler/rustc_abi/src/layout/ty.rs index 06bcb2b132597..b835909d2c2ca 100644 --- a/compiler/rustc_abi/src/layout/ty.rs +++ b/compiler/rustc_abi/src/layout/ty.rs @@ -299,6 +299,26 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { found } + pub fn complex_float(&self, cx: &C) -> Option + where + Ty: TyAbiInterface<'a, C> + Copy, + { + if !Ty::is_complex_number(*self, cx) { + return None; + } + + let BackendRepr::ScalarPair { a, b, .. } = self.backend_repr else { + return None; + }; + + debug_assert_eq!(a, b); + + match a.primitive() { + Primitive::Float(f) => Some(f), + _ => None, + } + } + /// Whether this type/layout has any padding that is dependent on a variant, i.e. has bytes that /// are padding for some, but not all, valid values of this type. pub fn has_variant_dependent_padding(&self, cx: &C) -> bool diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index a80088e41cd31..fd608fcf62919 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -1,5 +1,5 @@ use rustc_abi::{ - AddressSpace, Align, BackendRepr, HasDataLayout, Primitive, Reg, RegKind, TyAndLayout, + AddressSpace, Align, BackendRepr, Float, HasDataLayout, Primitive, Reg, RegKind, TyAndLayout, }; use crate::callconv::{ArgAttribute, FnAbi, PassMode, TyAbiInterface}; @@ -32,7 +32,14 @@ where // https://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let t = cx.target_spec(); - if t.abi_return_struct_as_int || opts.reg_struct_return { + if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { + // `_Complex _Float16` is returned as `<2 x half>`. + let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; + fn_abi.ret.cast_to(Reg { kind, size: fn_abi.ret.layout.size }); + } else if t.abi_return_struct_as_int + || opts.reg_struct_return + || fn_abi.ret.layout.is_complex_number(cx) + { // According to Clang, everyone but MSVC returns single-element // float aggregates directly in a floating-point register. if fn_abi.ret.layout.is_single_fp_element(cx) { diff --git a/compiler/rustc_target/src/callconv/x86_win32.rs b/compiler/rustc_target/src/callconv/x86_win32.rs index 824e7cc098a46..9303711b7f6ad 100644 --- a/compiler/rustc_target/src/callconv/x86_win32.rs +++ b/compiler/rustc_target/src/callconv/x86_win32.rs @@ -1,4 +1,4 @@ -use rustc_abi::{Align, HasDataLayout, Reg, TyAbiInterface}; +use rustc_abi::{Align, Float, HasDataLayout, Primitive, Reg, RegKind, TyAbiInterface}; use crate::callconv::FnAbi; use crate::spec::HasTargetSpec; @@ -25,7 +25,11 @@ pub(crate) fn compute_abi_info<'a, Ty, C>( // GCC used to apply the SysV rule here, breaking windows-gnu's ABI, but was fixed: // - reported in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82028 // - fixed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85667 - if t.abi_return_struct_as_int || opts.reg_struct_return { + if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { + // `_Complex _Float16` is returned as `<2 x half>`. + let kind = RegKind::Vector { hint_vector_elem: Primitive::Float(Float::F16) }; + fn_abi.ret.cast_to(Reg { kind, size: fn_abi.ret.layout.size }); + } else if t.abi_return_struct_as_int || opts.reg_struct_return { match fn_abi.ret.layout.size.bytes() { 1 => fn_abi.ret.cast_to(Reg::i8()), 2 => fn_abi.ret.cast_to(Reg::i16()), diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index 5c58eae7a5bb4..277936d0bac2a 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -13,15 +13,15 @@ //@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu //@ [WINDOWS_GNU] needs-llvm-components: x86 -// FIXME: the below revisions are deliberately disabled for now. +//@ revisions: I686 WIN32_MSVC WIN32_GNU +//@ [I686] compile-flags: --target i686-unknown-linux-gnu +//@ [I686] needs-llvm-components: x86 +//@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc +//@ [WIN32_MSVC] needs-llvm-components: x86 +//@ [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu +//@ [WIN32_GNU] needs-llvm-components: x86 -// revisions: I686 WIN32_MSVC WIN32_GNU -// [I686] compile-flags: --target i686-unknown-linux-gnu -// [I686] needs-llvm-components: x86 -// [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc -// [WIN32_MSVC] needs-llvm-components: x86 -// [WIN32_GNU] compile-flags: --target i686-pc-windows-gnu -// [WIN32_GNU] needs-llvm-components: x86 +// FIXME: the below revisions are deliberately disabled for now. // revisions: AARCH64 AARCH64_DARWIN AARCH64_MSVC ARM64EC // [AARCH64] compile-flags: --target aarch64-unknown-linux-gnu @@ -108,15 +108,15 @@ pub extern "C" fn cplx_f16(x: Complex) -> Complex { // AARCH64_MSVC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) // ARM64EC: define{{.*}} { half, half } @cplx_f16([2 x half] {{.*}}) // ARM: define{{.*}} i32 @cplx_f16([1 x i32] {{.*}}) - // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // I686: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // LOONGARCH64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // NVPTX: define{{.*}} { half, half } @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) // RISCV32: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // RISCV64: define{{.*}} { half, half } @cplx_f16(half {{.*}}, half {{.*}}) // S390X: define{{.*}} void @cplx_f16(ptr {{.*}} sret({ half, half }) {{.*}}, ptr {{.*}}) - // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) - // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval({ half, half }) {{.*}}) + // WIN32_GNU: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} <2 x half> @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_f16(i32 {{.*}}) // X86_64: define{{.*}} float @cplx_f16(float {{.*}}) @@ -133,7 +133,7 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // ARM: define{{.*}} { float, float } @cplx_f32({ float, float } {{.*}}) // BPF: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}}) - // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // I686: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) // LOONGARCH64: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) // MIPS64EL: define{{.*}} { float, float } @cplx_f32(float {{.*}}, float {{.*}}) @@ -149,8 +149,8 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // SPARC: define{{.*}} { float, float } @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) // WASM32: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) // WASM64: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, ptr {{.*}} byval({ float, float }) {{.*}}) - // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) - // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval({ float, float }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_f32(i64 {{.*}}) // X86_64: define{{.*}} double @cplx_f32(double {{.*}}) @@ -167,7 +167,7 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // ARM: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) // BPF: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [4 x i32] {{.*}}) - // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // I686: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) // LOONGARCH64: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) // MIPS64EL: define{{.*}} { double, double } @cplx_f64(double {{.*}}, double {{.*}}) @@ -183,8 +183,8 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // SPARC: define{{.*}} { double, double } @cplx_f64(ptr {{.*}} byval({ double, double }) {{.*}}) // WASM32: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) // WASM64: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) - // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, ptr {{.*}} byval({ double, double }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // WINDOWS_MSVC: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} { double, double } @cplx_f64({ double, double } {{.*}}) @@ -193,10 +193,10 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { #[no_mangle] pub extern "C" fn cplx_f128(x: Complex) -> Complex { - // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret({ fp128, fp128 }) {{.*}}, ptr {{.*}} byval({ fp128, fp128 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) x @@ -212,7 +212,7 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // ARM: define{{.*}} i16 @cplx_i8([1 x i32]{{.*}}) // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) // CSKY: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) - // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} {{.*}} i32 @cplx_i8(i32{{.*}}) // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i8(i64{{.*}}) // MIPS64EL: define{{.*}} { i8, i8 } @cplx_i8(i16 {{.*}}) @@ -228,8 +228,8 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // SPARC: define{{.*}} { i8, i8 } @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, ptr {{.*}} byval({ i8, i8 }) {{.*}}) - // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval({ i8, i8 }) {{.*}}) + // WIN32_GNU: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i16 @cplx_i8(i16 {{.*}}) // WINDOWS_MSVC: define{{.*}} i16 @cplx_i8(i16 {{.*}}) // X86_64: define{{.*}} i16 @cplx_i8(i16 {{.*}}) @@ -246,7 +246,7 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // ARM: define{{.*}} i32 @cplx_i16([1 x i32] {{.*}}) // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) - // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // LOONGARCH64: define{{.*}} {{.*}} i64 @cplx_i16(i64{{.*}}) // MIPS64EL: define{{.*}} { i16, i16 } @cplx_i16(i32 {{.*}}) @@ -262,8 +262,8 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // SPARC: define{{.*}} { i16, i16 } @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, ptr {{.*}} byval({ i16, i16 }) {{.*}}) - // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval({ i16, i16 }) {{.*}}) + // WIN32_GNU: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // WINDOWS_MSVC: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // X86_64: define{{.*}} i32 @cplx_i16(i32 {{.*}}) @@ -280,7 +280,7 @@ pub extern "C" fn cplx_i32(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, [2 x i32] {{.*}}) // BPF: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) - // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // I686: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) // LOONGARCH64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // MIPS64EL: define{{.*}} { i32, i32 } @cplx_i32(i64 {{.*}}) @@ -296,8 +296,8 @@ pub extern "C" fn cplx_i32(x: Complex) -> Complex { // SPARC: define{{.*}} { i32, i32 } @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, ptr {{.*}} byval({ i32, i32 }) {{.*}}) - // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) - // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval({ i32, i32 }) {{.*}}) + // WIN32_GNU: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // WINDOWS_MSVC: define{{.*}} i64 @cplx_i32(i64 {{.*}}) // X86_64: define{{.*}} i64 @cplx_i32(i64 {{.*}}) @@ -314,7 +314,7 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // BPF: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [4 x i32] {{.*}}) - // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}}) // LOONGARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) // MIPS64EL: define{{.*}} { i64, i64 } @cplx_i64(i64 {{.*}}, i64 {{.*}}) @@ -330,8 +330,8 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // SPARC: define{{.*}} { i64, i64 } @cplx_i64(ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WASM32: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) // WASM64: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) - // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, ptr {{.*}} byval({ i64, i64 }) {{.*}}) + // WIN32_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) + // WIN32_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // WINDOWS_GNU: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // WINDOWS_MSVC: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // X86_64: define{{.*}} { i64, i64 } @cplx_i64({ i64, i64 } {{.*}})