Skip to content

Commit a554f3f

Browse files
committed
feedback - exclude packed structs and add a test case for this
1 parent 8fed6c7 commit a554f3f

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

compiler/rustc_codegen_ssa/src/mir/operand.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
636636
}
637637

638638
mir::Operand::Constant(ref constant) => {
639-
if constant.ty().is_simd() {
639+
let constant_ty = constant.ty();
640+
// Make sure that constant SIMD vectors are passed as immediates.
641+
// This is needed for some intrinsics.
642+
if constant_ty.is_simd() && !constant_ty.is_packed() {
640643
let (llval, ty) = self.immediate_const_vector(bx, constant);
641644
OperandRef { val: OperandValue::Immediate(llval), layout: bx.layout_of(ty) }
642645
} else {

compiler/rustc_middle/src/ty/sty.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,14 @@ impl<'tcx> Ty<'tcx> {
10771077
}
10781078
}
10791079

1080+
#[inline]
1081+
pub fn is_packed(self) -> bool {
1082+
match self.kind() {
1083+
Adt(def, _) => def.repr().packed(),
1084+
_ => false,
1085+
}
1086+
}
1087+
10801088
pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
10811089
match self.kind() {
10821090
Array(ty, _) | Slice(ty) => *ty,

tests/codegen/const-vector.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
//@ compile-flags: -C no-prepopulate-passes -Copt-level=0
22

3-
// Ensuring the 2 different ways of creating const vectors works
3+
// This test checks that constants of SIMD type are passed as immediate vectors.
4+
// We ensure that both vector representations (struct with fields and struct wrapping array) work.
45
#![crate_type = "lib"]
56
#![feature(abi_unadjusted)]
6-
#![allow(non_camel_case_types)]
77
#![feature(const_trait_impl)]
88
#![feature(repr_simd)]
99
#![feature(rustc_attrs)]
1010
#![feature(simd_ffi)]
11+
#![allow(non_camel_case_types)]
1112

1213
// Setting up structs that can be used as const vectors
1314
#[repr(simd)]
@@ -26,6 +27,10 @@ pub struct f32x2(f32, f32);
2627
#[derive(Clone)]
2728
pub struct f32x2_arr([f32; 2]);
2829

30+
#[repr(simd, packed)]
31+
#[derive(Copy, Clone)]
32+
pub struct Simd<T, const N: usize>([T; N]);
33+
2934
// The following functions are required for the tests to ensure
3035
// that they are called with a const vector
3136

@@ -59,6 +64,20 @@ extern "unadjusted" {
5964
fn test_f32x2_arr(a: f32x2_arr);
6065
}
6166

67+
extern "unadjusted" {
68+
#[no_mangle]
69+
fn test_simd(a: Simd<i32, 4>);
70+
}
71+
72+
extern "unadjusted" {
73+
#[no_mangle]
74+
fn test_simd_unaligned(a: Simd<i32, 3>);
75+
}
76+
77+
// Ensure the packed variant of the simd struct does not become a const vector
78+
// if the size is not a power of 2
79+
// CHECK: %"Simd<i32, 3>" = type { [3 x i32] }
80+
6281
pub fn do_call() {
6382
unsafe {
6483
// CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
@@ -78,5 +97,11 @@ pub fn do_call() {
7897

7998
// CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
8099
test_f32x2_arr(const { f32x2_arr([0.32, 0.64]) });
100+
101+
// CHECK: call void @test_simd(<4 x i32> %4
102+
test_simd(Simd::<i32, 4>([2, 4, 6, 8]));
103+
104+
// CHECK: call void @test_simd_unaligned(%"Simd<i32, 3>" %8
105+
test_simd_unaligned(Simd::<i32, 3>([2, 4, 6]));
81106
}
82107
}

0 commit comments

Comments
 (0)