-
-
Notifications
You must be signed in to change notification settings - Fork 15.4k
fix is_homogeneous_aggregate: use unit size, not total size
#161394
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -26,7 +26,7 @@ where | |
| let valid_unit = match unit.kind { | ||
| RegKind::Integer => false, | ||
| RegKind::Float => true, | ||
| RegKind::Vector { .. } => size.bits() == 64 || size.bits() == 128, | ||
| RegKind::Vector { .. } => unit.size.bits() == 64 || unit.size.bits() == 128, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }; | ||
|
|
||
| valid_unit.then_some(Uniform::consecutive(unit, size)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -36,7 +36,7 @@ where | |
| let valid_unit = match unit.kind { | ||
| RegKind::Integer => false, | ||
| RegKind::Float => true, | ||
| RegKind::Vector { .. } => arg.layout.size.bits() == 128, | ||
| RegKind::Vector { .. } => unit.size.bits() == 128, | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| }; | ||
|
|
||
| valid_unit.then_some(Uniform::consecutive(unit, arg.layout.size)) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -496,4 +496,5 @@ pub mod simd { | |
| pub type i64x8 = Simd<i64, 8>; | ||
|
|
||
| pub type u8x16 = Simd<u8, 16>; | ||
| pub type u64x2 = Simd<u8, 16>; | ||
| } | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Worth adding |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,84 @@ | ||
| //@ add-minicore | ||
| //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 | ||
| // | ||
| //@ revisions: linux win | ||
| //@[linux] compile-flags: --target aarch64-unknown-linux-gnu | ||
| //@[win] compile-flags: --target aarch64-pc-windows-msvc | ||
| // | ||
| //@ needs-llvm-components: aarch64 | ||
|
|
||
| // Test that homogeneous aggregates are passed and returned with the correct ABI. | ||
|
|
||
| #![feature(no_core, lang_items)] | ||
| #![crate_type = "lib"] | ||
| #![no_core] | ||
|
|
||
| extern crate minicore; | ||
| use minicore::simd::*; | ||
| use minicore::*; | ||
|
|
||
| // A homogeneous float aggregate. | ||
| #[repr(C)] | ||
| pub struct Hfa { | ||
| pub a: f32, | ||
| pub b: f32, | ||
| } | ||
| impl Copy for Hfa {} | ||
|
|
||
| // CHECK: define void @test_hfa([2 x float] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa(a: Hfa) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| // Fields can be vectors too. | ||
| #[repr(C)] | ||
| pub struct Hfa2V2F64 { | ||
| pub a: f64x2, | ||
| pub b: f64x2, | ||
| } | ||
|
|
||
| // CHECK: define void @test_hfa_2_f64x2([2 x <2 x double>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_f64x2(a: Hfa2V2F64) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa2V2U64 { | ||
| pub a: u64x2, | ||
| pub b: u64x2, | ||
| } | ||
|
|
||
| // CHECK: define void @test_hfa_2_u64x2([2 x <16 x i8>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_u64x2(a: Hfa2V2U64) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa2V2F32 { | ||
| pub a: f32x2, | ||
| pub b: f32x2, | ||
| } | ||
|
|
||
| // CHECK: define void @test_hfa_2_f32x2([2 x <2 x float>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_f32x2(a: Hfa2V2F32) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa4V2F64 { | ||
| pub a: f64x2, | ||
| pub b: f64x2, | ||
| pub c: f64x2, | ||
| pub d: f64x2, | ||
| } | ||
|
|
||
| // CHECK: define void @test_hfa_4_f64x2([4 x <2 x double>] %0) | ||
| #[unsafe(no_mangle)] | ||
| #[target_feature(enable = "neon")] | ||
| pub extern "C" fn test_hfa_4_f64x2(a: Hfa4V2F64) { | ||
| hint::black_box(a); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| //@ add-minicore | ||
| //@ compile-flags: -Cno-prepopulate-passes -Copt-level=0 | ||
| // | ||
| //@ revisions: ppc64 ppc64_vsx ppc64le | ||
| //@[ppc64] compile-flags: --target powerpc64-unknown-linux-gnu | ||
| //@[ppc64_vsx] compile-flags: --target powerpc64-unknown-linux-gnu -Ctarget-feature=+vsx | ||
| //@[ppc64le] compile-flags: --target powerpc64le-unknown-linux-gnu | ||
| // | ||
| //@ needs-llvm-components: powerpc | ||
|
|
||
| // Test that homogeneous aggregates are passed and returned with the correct ABI. | ||
|
|
||
| #![feature(no_core, lang_items)] | ||
| #![crate_type = "lib"] | ||
| #![no_core] | ||
|
|
||
| extern crate minicore; | ||
| use minicore::simd::*; | ||
| use minicore::*; | ||
|
|
||
| // A homogeneous float aggregate. | ||
| #[repr(C)] | ||
| pub struct Hfa { | ||
| pub a: f32, | ||
| pub b: f32, | ||
| } | ||
| impl Copy for Hfa {} | ||
|
|
||
| // ppc64: define void @test_hfa(i64 %0) | ||
| // ppc64_vsx: define void @test_hfa(i64 %0) | ||
| // ppc64le: define void @test_hfa([2 x float] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa(a: Hfa) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| // Fields can be vectors too. | ||
| #[repr(C)] | ||
| pub struct Hfa2V2F64 { | ||
| pub a: f64x2, | ||
| pub b: f64x2, | ||
| } | ||
|
|
||
| // ppc64: define void @test_hfa_2_f64x2([2 x i128] %0) | ||
| // ppc64_vsx: define void @test_hfa_2_f64x2([2 x i128] %0) | ||
| // ppc64le: define void @test_hfa_2_f64x2([2 x <2 x double>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_f64x2(a: Hfa2V2F64) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa2V2U64 { | ||
| pub a: u64x2, | ||
| pub b: u64x2, | ||
| } | ||
|
|
||
| // ppc64: define void @test_hfa_2_u64x2([2 x i128] %0) | ||
| // ppc64_vsx: define void @test_hfa_2_u64x2([2 x i128] %0) | ||
| // ppc64le: define void @test_hfa_2_u64x2([2 x <16 x i8>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_u64x2(a: Hfa2V2U64) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa2V2F32 { | ||
| pub a: f32x2, | ||
| pub b: f32x2, | ||
| } | ||
|
|
||
| // On PowerPC only 128-bit units are eligible for HVA. | ||
| // | ||
| // ppc64: define void @test_hfa_2_f32x2([2 x i64] %0) | ||
| // ppc64_vsx: define void @test_hfa_2_f32x2([2 x i64] %0) | ||
| // ppc64le: define void @test_hfa_2_f32x2([2 x i64] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_2_f32x2(a: Hfa2V2F32) { | ||
| hint::black_box(a); | ||
| } | ||
|
|
||
| #[repr(C)] | ||
| pub struct Hfa4V2F64 { | ||
| pub a: f64x2, | ||
| pub b: f64x2, | ||
| pub c: f64x2, | ||
| pub d: f64x2, | ||
| } | ||
|
|
||
| // ppc64: define void @test_hfa_4_f64x2([4 x i128] %0) | ||
| // ppc64_vsx: define void @test_hfa_4_f64x2([4 x i128] %0) | ||
| // ppc64le: define void @test_hfa_4_f64x2([4 x <2 x double>] %0) | ||
| #[unsafe(no_mangle)] | ||
| pub extern "C" fn test_hfa_4_f64x2(a: Hfa4V2F64) { | ||
| hint::black_box(a); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -52,45 +52,46 @@ mod tests { | |
| // CHECK: define [2 x <1 x ptr>] @pair_ptrx1_t([2 x <1 x ptr>] {{.*}} %0) | ||
| #[unsafe(no_mangle)] extern "C" fn pair_ptrx1_t(x: Pair<Simd<*const (), 1>>) -> Pair<Simd<*const (), 1>> { x } | ||
|
|
||
| // When it fits in a 128-bit register, it's passed directly. | ||
| // When the fields are not 64 or 128 bits in size, they do not qualify as a homogeneous | ||
| // aggregate, and passed as type-erased sequences of integers. | ||
|
|
||
| // CHECK: define [4 x <4 x i8>] @quad_int8x4_t([4 x <4 x i8>] {{.*}} %0) | ||
| // CHECK: define [2 x i64] @quad_int8x4_t([2 x i64] {{.*}} %0) | ||
|
Comment on lines
+55
to
+58
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these previously passed the aggregate check, but that was wrong |
||
| #[unsafe(no_mangle)] extern "C" fn quad_int8x4_t(x: Quad<Simd<i8, 4>>) -> Quad<Simd<i8, 4>> { x } | ||
|
|
||
| // CHECK: define [4 x <2 x i16>] @quad_int16x2_t([4 x <2 x i16>] {{.*}} %0) | ||
| // CHECK: define [2 x i64] @quad_int16x2_t([2 x i64] {{.*}} %0) | ||
| #[unsafe(no_mangle)] extern "C" fn quad_int16x2_t(x: Quad<Simd<i16, 2>>) -> Quad<Simd<i16, 2>> { x } | ||
|
|
||
| // CHECK: define [4 x <1 x i32>] @quad_int32x1_t([4 x <1 x i32>] {{.*}} %0) | ||
| // CHECK: define [2 x i64] @quad_int32x1_t([2 x i64] {{.*}} %0) | ||
| #[unsafe(no_mangle)] extern "C" fn quad_int32x1_t(x: Quad<Simd<i32, 1>>) -> Quad<Simd<i32, 1>> { x } | ||
|
|
||
| // CHECK: define [4 x <2 x half>] @quad_float16x2_t([4 x <2 x half>] {{.*}} %0) | ||
| // CHECK: define [2 x i64] @quad_float16x2_t([2 x i64] {{.*}} %0) | ||
| #[unsafe(no_mangle)] extern "C" fn quad_float16x2_t(x: Quad<Simd<f16, 2>>) -> Quad<Simd<f16, 2>> { x } | ||
|
|
||
| // CHECK: define [4 x <1 x float>] @quad_float32x1_t([4 x <1 x float>] {{.*}} %0) | ||
| // CHECK: define [2 x i64] @quad_float32x1_t([2 x i64] {{.*}} %0) | ||
| #[unsafe(no_mangle)] extern "C" fn quad_float32x1_t(x: Quad<Simd<f32, 1>>) -> Quad<Simd<f32, 1>> { x } | ||
|
|
||
| // When it doesn't quite fit, padding is added which does erase the type. | ||
|
|
||
| // CHECK: define [2 x i64] @triple_int8x4_t | ||
| #[unsafe(no_mangle)] extern "C" fn triple_int8x4_t(x: Triple<Simd<i8, 4>>) -> Triple<Simd<i8, 4>> { x } | ||
|
|
||
| // Other configurations are not passed by-value but indirectly. | ||
| // Other configurations passed directly when they qualify as a homogeneous aggregate. | ||
|
|
||
| // CHECK: define void @pair_int128x1_t | ||
| // CHECK: define [2 x <1 x i128>] @pair_int128x1_t([2 x <1 x i128>] | ||
|
Comment on lines
-77
to
+80
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. these are now recognized as homogeneous aggregates |
||
| #[unsafe(no_mangle)] extern "C" fn pair_int128x1_t(x: Pair<Simd<i128, 1>>) -> Pair<Simd<i128, 1>> { x } | ||
|
|
||
| // CHECK: define void @pair_float128x1_t | ||
| // CHECK: define [2 x <1 x fp128>] @pair_float128x1_t([2 x <1 x fp128>] | ||
| #[unsafe(no_mangle)] extern "C" fn pair_float128x1_t(x: Pair<Simd<f128, 1>>) -> Pair<Simd<f128, 1>> { x } | ||
|
|
||
| // CHECK: define void @pair_int8x16_t | ||
| // CHECK: define [2 x <16 x i8>] @pair_int8x16_t([2 x <16 x i8>] | ||
| #[unsafe(no_mangle)] extern "C" fn pair_int8x16_t(x: Pair<Simd<i8, 16>>) -> Pair<Simd<i8, 16>> { x } | ||
|
|
||
| // CHECK: define void @pair_int16x8_t | ||
| // CHECK: define [2 x <8 x i16>] @pair_int16x8_t([2 x <8 x i16>] | ||
| #[unsafe(no_mangle)] extern "C" fn pair_int16x8_t(x: Pair<Simd<i16, 8>>) -> Pair<Simd<i16, 8>> { x } | ||
|
|
||
| // CHECK: define void @triple_int16x8_t | ||
| // CHECK: define [3 x <8 x i16>] @triple_int16x8_t([3 x <8 x i16>] | ||
| #[unsafe(no_mangle)] extern "C" fn triple_int16x8_t(x: Triple<Simd<i16, 8>>) -> Triple<Simd<i16, 8>> { x } | ||
|
|
||
| // CHECK: define void @quad_int16x8_t | ||
| // CHECK: define [4 x <8 x i16>] @quad_int16x8_t([4 x <8 x i16>] | ||
| #[unsafe(no_mangle)] extern "C" fn quad_int16x8_t(x: Quad<Simd<i16, 8>>) -> Quad<Simd<i16, 8>> { x } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://github.com/llvm/llvm-project/blob/a6f35d1c87513614baaa2f626257e8d4b8320fef/clang/lib/CodeGen/Targets/AArch64.cpp#L676-L700
View changes since the review