diff --git a/compiler/rustc_target/src/callconv/x86.rs b/compiler/rustc_target/src/callconv/x86.rs index fd608fcf62919..45dee0bb983d7 100644 --- a/compiler/rustc_target/src/callconv/x86.rs +++ b/compiler/rustc_target/src/callconv/x86.rs @@ -32,8 +32,10 @@ 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 let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) { - // `_Complex _Float16` is returned as `<2 x half>`. + if let Some(Float::F16) = fn_abi.ret.layout.complex_float(cx) + && cx.target_spec().rustc_abi == Some(RustcAbi::X86Sse2) + { + // With SSE2 `_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 diff --git a/tests/codegen-llvm/complex-abi.rs b/tests/codegen-llvm/complex-abi.rs index 81d93b704ee1c..9ee93d3845950 100644 --- a/tests/codegen-llvm/complex-abi.rs +++ b/tests/codegen-llvm/complex-abi.rs @@ -13,7 +13,9 @@ //@ [WINDOWS_GNU] compile-flags: --target x86_64-pc-windows-gnu //@ [WINDOWS_GNU] needs-llvm-components: x86 -//@ revisions: I686 WIN32_MSVC WIN32_GNU +//@ revisions: I586 I686 WIN32_MSVC WIN32_GNU +//@ [I586] compile-flags: --target i586-unknown-linux-gnu +//@ [I586] needs-llvm-components: x86 //@ [I686] compile-flags: --target i686-unknown-linux-gnu //@ [I686] needs-llvm-components: x86 //@ [WIN32_MSVC] compile-flags: --target i686-pc-windows-msvc @@ -102,6 +104,7 @@ pub extern "C" fn cplx_f16(x: Complex) -> Complex { // AARCH64_MSVC: define{{.*}} [2 x half] @cplx_f16([2 x half] {{.*}}) // ARM64EC: define{{.*}} [2 x half] @cplx_f16([2 x half] {{.*}}) // ARM: define{{.*}} [2 x half] @cplx_f16([2 x half] {{.*}}) + // I586: define{{.*}} i32 @cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // 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 } {{.*}}) @@ -127,6 +130,7 @@ pub extern "C" fn cplx_f32(x: Complex) -> Complex { // ARM: define{{.*}} [2 x float] @cplx_f32([2 x float] {{.*}}) // BPF: define{{.*}} void @cplx_f32(ptr {{.*}} sret({ float, float }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_f32([2 x i32] {{.*}}) + // I586: define{{.*}} i64 @cplx_f32(ptr {{.*}} byval([8 x i8]) {{.*}}) // 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 } {{.*}}) @@ -161,6 +165,7 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { // ARM: define{{.*}} [2 x double] @cplx_f64([2 x double] {{.*}}) // BPF: define{{.*}} void @cplx_f64(ptr {{.*}} sret({ double, double }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, [4 x i32] {{.*}}) + // I586: define{{.*}} void @cplx_f64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // 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 } {{.*}}) @@ -188,6 +193,7 @@ pub extern "C" fn cplx_f64(x: Complex) -> Complex { #[no_mangle] pub extern "C" fn cplx_f128(x: Complex) -> Complex { // AARCH64: define{{.*}} [2 x fp128] {{.*}}) + // I586: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // I686: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}} byval([32 x i8]) {{.*}}) // WASM32: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) // WASM64: define{{.*}} void @cplx_f128(ptr {{.*}} sret([32 x i8]) {{.*}}, ptr {{.*}}) @@ -209,6 +215,7 @@ pub extern "C" fn cplx_i8(x: Complex) -> Complex { // ARM: define{{.*}} i32 @cplx_i8(i32{{.*}}) // BPF: define{{.*}} void @cplx_i8(ptr {{.*}} sret({ i8, i8 }) {{.*}}, i16 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i8(i32{{.*}}) + // I586: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // I686: define{{.*}} i16 @cplx_i8(ptr {{.*}} byval([2 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} i32 @cplx_i8(i32{{.*}}) // LOONGARCH64: define{{.*}} i64 @cplx_i8(i64{{.*}}) @@ -243,6 +250,7 @@ pub extern "C" fn cplx_i16(x: Complex) -> Complex { // ARM: define{{.*}} i32 @cplx_i16(i32{{.*}}) // BPF: define{{.*}} void @cplx_i16(ptr {{.*}} sret({ i16, i16 }) {{.*}}, i32 {{.*}}) // CSKY: define{{.*}} i32 @cplx_i16(i32 {{.*}}) + // I586: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // I686: define{{.*}} i32 @cplx_i16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} i32 @cplx_i16(i32 {{.*}}) // LOONGARCH64: define{{.*}} i64 @cplx_i16(i64{{.*}}) @@ -277,6 +285,7 @@ pub extern "C" fn cplx_i32(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i32(ptr {{.*}} sret([8 x i8]) {{.*}}, [2 x i32] {{.*}}) // BPF: define{{.*}} void @cplx_i32(ptr {{.*}} sret({ i32, i32 }) {{.*}}, i64 {{.*}}) // CSKY: define{{.*}} [2 x i32] @cplx_i32([2 x i32] {{.*}}) + // I586: define{{.*}} i64 @cplx_i32(ptr {{.*}} byval([8 x i8]) {{.*}}) // 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 {{.*}}) @@ -311,6 +320,7 @@ pub extern "C" fn cplx_i64(x: Complex) -> Complex { // ARM: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, [2 x i64] {{.*}}) // BPF: define{{.*}} void @cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, [4 x i32] {{.*}}) + // I586: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // I686: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} void @cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // LOONGARCH64: define{{.*}} [2 x i64] @cplx_i64([2 x i64] {{.*}}) @@ -350,6 +360,7 @@ pub extern "C" fn wrapper_cplx_i64( // ARM: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, [2 x i64] {{.*}}) // BPF: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret({ i64, i64 }) {{.*}}, [2 x i64] {{.*}}) // CSKY: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, [4 x i32] {{.*}}) + // I586: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // I686: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}} byval([16 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} void @wrapper_cplx_i64(ptr {{.*}} sret([16 x i8]) {{.*}}, ptr {{.*}}) // LOONGARCH64: define{{.*}} [2 x i64] @wrapper_cplx_i64([2 x i64] {{.*}}) @@ -383,6 +394,7 @@ pub extern "C" fn wrapper_cplx_f16( // AARCH64_MSVC: define{{.*}} [2 x half] @wrapper_cplx_f16([2 x half] {{.*}}) // ARM64EC: define{{.*}} [2 x half] @wrapper_cplx_f16([2 x half] {{.*}}) // ARM: define{{.*}} [2 x half] @wrapper_cplx_f16([2 x half] {{.*}}) + // I586: define{{.*}} i32 @wrapper_cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // I686: define{{.*}} <2 x half> @wrapper_cplx_f16(ptr {{.*}} byval([4 x i8]) {{.*}}) // LOONGARCH32: define{{.*}} { half, half } @wrapper_cplx_f16({ half, half } {{.*}}) // LOONGARCH64: define{{.*}} { half, half } @wrapper_cplx_f16({ half, half } {{.*}})