diff --git a/src/librustc_trans/trans/intrinsic.rs b/src/librustc_trans/trans/intrinsic.rs index ed75445b993..b22c7f763f0 100644 --- a/src/librustc_trans/trans/intrinsic.rs +++ b/src/librustc_trans/trans/intrinsic.rs @@ -313,7 +313,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, (_, "size_of") => { let tp_ty = *substs.types.get(FnSpace, 0); let lltp_ty = type_of::type_of(ccx, tp_ty); - C_uint(ccx, machine::llsize_of_real(ccx, lltp_ty)) + C_uint(ccx, machine::llsize_of_alloc(ccx, lltp_ty)) } (_, "min_align_of") => { let tp_ty = *substs.types.get(FnSpace, 0); diff --git a/src/librustc_trans/trans/machine.rs b/src/librustc_trans/trans/machine.rs index 41738f1e58f..95d67cd54c1 100644 --- a/src/librustc_trans/trans/machine.rs +++ b/src/librustc_trans/trans/machine.rs @@ -43,8 +43,10 @@ pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> llsize { // Returns, as near as we can figure, the "real" size of a type. As in, the // bits in this number of bytes actually carry data related to the datum -// with the type. Not junk, padding, accidentally-damaged words, or -// whatever. Rounds up to the nearest byte though, so if you have a 1-bit +// with the type. Not junk, accidentally-damaged words, or whatever. +// Note that padding of the type will be included for structs, but not for the +// other types (i.e. SIMD types). +// Rounds up to the nearest byte though, so if you have a 1-bit // value, we return 1 here, not 0. Most of rustc works in bytes. Be warned // that LLVM *does* distinguish between e.g. a 1-bit value and an 8-bit value // at the codegen level! In general you should prefer `llbitsize_of_real` diff --git a/src/test/run-pass/simd-size-align.rs b/src/test/run-pass/simd-size-align.rs new file mode 100644 index 00000000000..582810f0def --- /dev/null +++ b/src/test/run-pass/simd-size-align.rs @@ -0,0 +1,70 @@ +// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(simd)] +#![allow(non_camel_case_types)] + +use std::mem; + +/// `T` should satisfy `size_of T (mod min_align_of T) === 0` to be stored at `Vec` properly +/// Please consult the issue #20460 +fn check() { + assert_eq!(mem::size_of::() % mem::min_align_of::(), 0) +} + +fn main() { + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); +} + +#[simd] struct u8x2(u8, u8); +#[simd] struct u8x3(u8, u8, u8); +#[simd] struct u8x4(u8, u8, u8, u8); +#[simd] struct u8x5(u8, u8, u8, u8, u8); +#[simd] struct u8x6(u8, u8, u8, u8, u8, u8); +#[simd] struct u8x7(u8, u8, u8, u8, u8, u8, u8); +#[simd] struct u8x8(u8, u8, u8, u8, u8, u8, u8, u8); + +#[simd] struct i16x2(i16, i16); +#[simd] struct i16x3(i16, i16, i16); +#[simd] struct i16x4(i16, i16, i16, i16); +#[simd] struct i16x5(i16, i16, i16, i16, i16); +#[simd] struct i16x6(i16, i16, i16, i16, i16, i16); +#[simd] struct i16x7(i16, i16, i16, i16, i16, i16, i16); +#[simd] struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16); + +#[simd] struct f32x2(f32, f32); +#[simd] struct f32x3(f32, f32, f32); +#[simd] struct f32x4(f32, f32, f32, f32); +#[simd] struct f32x5(f32, f32, f32, f32, f32); +#[simd] struct f32x6(f32, f32, f32, f32, f32, f32); +#[simd] struct f32x7(f32, f32, f32, f32, f32, f32, f32); +#[simd] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);