diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 2f944e49b1516..ccda25eff39c2 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -41,7 +41,7 @@ use middle::cfg; use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem}; use middle::weak_lang_items; use middle::subst::{Subst, Substs}; -use middle::ty::{self, Ty, ClosureTyper}; +use middle::ty::{self, Ty, ClosureTyper, type_is_simd, simd_size}; use session::config::{self, NoDebugInfo}; use session::Session; use trans::_match; @@ -52,7 +52,7 @@ use trans::callee; use trans::cleanup::CleanupMethods; use trans::cleanup; use trans::closure; -use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_integral}; +use trans::common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_integral}; use trans::common::{C_null, C_struct_in_context, C_u64, C_u8, C_undef}; use trans::common::{CrateContext, ExternMap, FunctionContext}; use trans::common::{Result, NodeIdAndSpan}; @@ -824,6 +824,15 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>( let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0, false); (ICmp(cx, llvm::IntEQ, rhs, zero, debug_loc), false) } + ty::ty_struct(_, _) if type_is_simd(cx.tcx(), rhs_t) => { + let mut res = C_bool(cx.ccx(), false); + for i in 0 .. simd_size(cx.tcx(), rhs_t) { + res = Or(cx, res, + IsNull(cx, + ExtractElement(cx, rhs, C_int(cx.ccx(), i as i64))), debug_loc); + } + (res, false) + } _ => { cx.sess().bug(&format!("fail-if-zero on unexpected type: {}", ty_to_string(cx.tcx(), rhs_t))); diff --git a/src/test/run-pass/simd-binop.rs b/src/test/run-pass/simd-binop.rs index 0d26b75c2ad7f..9f7b78e4e3354 100644 --- a/src/test/run-pass/simd-binop.rs +++ b/src/test/run-pass/simd-binop.rs @@ -32,6 +32,7 @@ pub fn main() { assert!(eq_u32x4(u32x4(1, 2, 3, 4) + u32x4(4, 3, 2, 1), u32x4(5, 5, 5, 5))); assert!(eq_u32x4(u32x4(4, 5, 6, 7) - u32x4(4, 3, 2, 1), u32x4(0, 2, 4, 6))); assert!(eq_u32x4(u32x4(1, 2, 3, 4) * u32x4(4, 3, 2, 1), u32x4(4, 6, 6, 4))); + assert!(eq_u32x4(u32x4(1, 2, 3, 4) / u32x4(4, 3, 2, 1), u32x4(0, 0, 1, 4))); assert!(eq_u32x4(u32x4(1, 2, 3, 4) & u32x4(4, 3, 2, 1), u32x4(0, 2, 2, 0))); assert!(eq_u32x4(u32x4(1, 2, 3, 4) | u32x4(4, 3, 2, 1), u32x4(5, 3, 3, 5))); assert!(eq_u32x4(u32x4(1, 2, 3, 4) ^ u32x4(4, 3, 2, 1), u32x4(5, 1, 1, 5))); @@ -41,6 +42,7 @@ pub fn main() { assert!(eq_i32x4(i32x4(1, 2, 3, 4) + i32x4(4, 3, 2, 1), i32x4(5, 5, 5, 5))); assert!(eq_i32x4(i32x4(1, 2, 3, 4) - i32x4(4, 3, 2, 1), i32x4(-3, -1, 1, 3))); assert!(eq_i32x4(i32x4(1, 2, 3, 4) * i32x4(4, 3, 2, 1), i32x4(4, 6, 6, 4))); + assert!(eq_i32x4(i32x4(1, 2, 3, 4) / i32x4(4, 3, 2, 1), i32x4(0, 0, 1, 4))); assert!(eq_i32x4(i32x4(1, 2, 3, 4) & i32x4(4, 3, 2, 1), i32x4(0, 2, 2, 0))); assert!(eq_i32x4(i32x4(1, 2, 3, 4) | i32x4(4, 3, 2, 1), i32x4(5, 3, 3, 5))); assert!(eq_i32x4(i32x4(1, 2, 3, 4) ^ i32x4(4, 3, 2, 1), i32x4(5, 1, 1, 5)));