]> git.lizzy.rs Git - rust.git/commitdiff
Revamp SIMD intrinsic trans error handling.
authorHuon Wilson <dbau.pp+github@gmail.com>
Fri, 14 Aug 2015 22:20:22 +0000 (15:20 -0700)
committerHuon Wilson <dbau.pp+github@gmail.com>
Mon, 17 Aug 2015 21:48:44 +0000 (14:48 -0700)
Factor out common pieces, follow `expected ..., found ...` convention
everywhere.

src/librustc_trans/trans/intrinsic.rs
src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs
src/test/compile-fail/simd-intrinsic-generic-cast.rs
src/test/compile-fail/simd-intrinsic-generic-comparison.rs
src/test/compile-fail/simd-intrinsic-generic-elements.rs

index dbfd76d3082c5faf620ab8817ef26505cfa3e6d5..185a5cb47466e0222e71cd4a1f364278fd735ec1 100644 (file)
@@ -1329,14 +1329,33 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
      call_debug_location: DebugLoc,
      call_info: NodeIdAndSpan) -> ValueRef
 {
+    // macros for error handling:
+    macro_rules! emit_error {
+        ($msg: tt) => {
+            emit_error!($msg, )
+        };
+        ($msg: tt, $($fmt: tt)*) => {
+            bcx.sess().span_err(call_info.span,
+                                &format!(concat!("invalid monomorphization of `{}` intrinsic: ",
+                                                 $msg),
+                                         name, $($fmt)*));
+        }
+    }
     macro_rules! require {
         ($cond: expr, $($fmt: tt)*) => {
             if !$cond {
-                bcx.sess().span_err(call_info.span, &format!($($fmt)*));
+                emit_error!($($fmt)*);
                 return C_null(llret_ty)
             }
         }
     }
+    macro_rules! require_simd {
+        ($ty: expr, $position: expr) => {
+            require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty)
+        }
+    }
+
+
 
     let tcx = bcx.tcx();
     let arg_tys = match callee_ty.sty {
@@ -1346,6 +1365,12 @@ macro_rules! require {
         _ => unreachable!()
     };
 
+    // every intrinsic takes a SIMD vector as its first argument
+    require_simd!(arg_tys[0], "input");
+    let in_ty = arg_tys[0];
+    let in_elem = arg_tys[0].simd_type(tcx);
+    let in_len = arg_tys[0].simd_size(tcx);
+
     let comparison = match name {
         "simd_eq" => Some(ast::BiEq),
         "simd_ne" => Some(ast::BiNe),
@@ -1357,30 +1382,23 @@ macro_rules! require {
     };
 
     if let Some(cmp_op) = comparison {
-        assert_eq!(arg_tys.len(), 2);
-        require!(arg_tys[0].is_simd(),
-                 "SIMD comparison intrinsic monomorphized for non-SIMD argument type `{}`",
-                 arg_tys[0]);
-        require!(ret_ty.is_simd(),
-                 "SIMD comparison intrinsic monomorphized for non-SIMD return type `{}`",
-                 ret_ty);
-
-        let in_len = arg_tys[0].simd_size(tcx);
+        require_simd!(ret_ty, "return");
+
         let out_len = ret_ty.simd_size(tcx);
         require!(in_len == out_len,
-                 "SIMD cast intrinsic monomorphized with input type `{}` and \
-                  return type `{}` with different lengths: {} vs. {}",
-                 arg_tys[0],
-                 ret_ty,
-                 in_len,
-                 out_len);
+                 "expected return type with length {} (same as input type `{}`), \
+                  found `{}` with length {}",
+                 in_len, in_ty,
+                 ret_ty, out_len);
         require!(llret_ty.element_type().kind() == llvm::Integer,
-                 "SIMD comparison intrinsic monomorphized with non-integer return");
+                 "expected return type with integer elements, found `{}` with non-integer `{}`",
+                 ret_ty,
+                 ret_ty.simd_type(tcx));
 
         return compare_simd_types(bcx,
                                   llargs[0],
                                   llargs[1],
-                                  arg_tys[0].simd_type(tcx),
+                                  in_elem,
                                   llret_ty,
                                   cmp_op,
                                   call_debug_location)
@@ -1390,24 +1408,20 @@ macro_rules! require {
         let n: usize = match name["simd_shuffle".len()..].parse() {
             Ok(n) => n,
             Err(_) => tcx.sess.span_bug(call_info.span,
-                                          "bad `simd_shuffle` instruction only caught in trans?")
+                                        "bad `simd_shuffle` instruction only caught in trans?")
         };
 
-        require!(arg_tys[0].is_simd(),
-                 "SIMD shuffle intrinsic monomorphized with non-SIMD input type `{}`",
-                 arg_tys[0]);
-        require!(ret_ty.is_simd(),
-                 "SIMD shuffle intrinsic monomorphized for non-SIMD return type `{}`",
-                 ret_ty);
+        require_simd!(ret_ty, "return");
 
-        let in_len = arg_tys[0].simd_size(tcx);
         let out_len = ret_ty.simd_size(tcx);
         require!(out_len == n,
-                 "SIMD shuffle intrinsic monomorphized with return type of length {} (expected {})",
-                 out_len, n);
-        require!(arg_tys[0].simd_type(tcx) == ret_ty.simd_type(tcx),
-                 "SIMD shuffle intrinsic monomorphized with different \
-                  input and return element types");
+                 "expected return type of length {}, found `{}` with length {}",
+                 n, ret_ty, out_len);
+        require!(in_elem == ret_ty.simd_type(tcx),
+                 "expected return element type `{}` (element of input `{}`), \
+                  found `{}` with element type `{}`",
+                 in_elem, in_ty,
+                 ret_ty, ret_ty.simd_type(tcx));
 
         let total_len = in_len as u64 * 2;
 
@@ -1425,17 +1439,12 @@ macro_rules! require {
                 let c = const_to_opt_uint(val);
                 match c {
                     None => {
-                        bcx.sess().span_err(call_info.span,
-                                            &format!("SIMD shuffle intrinsic argument #{} \
-                                                      is not a constant",
-                                                     arg_idx));
+                        emit_error!("shuffle index #{} is not a constant", arg_idx);
                         None
                     }
                     Some(idx) if idx >= total_len => {
-                        bcx.sess().span_err(call_info.span,
-                                            &format!("SIMD shuffle intrinsic argument #{} \
-                                                      is out of bounds (limit {})",
-                                                     arg_idx, total_len));
+                        emit_error!("shuffle index #{} is out of bounds (limit {})",
+                                    arg_idx, total_len);
                         None
                     }
                     Some(idx) => Some(C_i32(bcx.ccx(), idx as i32)),
@@ -1451,45 +1460,32 @@ macro_rules! require {
     }
 
     if name == "simd_insert" {
-        require!(arg_tys[0].is_simd(),
-                 "SIMD insert intrinsic monomorphized for non-SIMD input type");
-
-        let elem_ty = arg_tys[0].simd_type(tcx);
-        require!(arg_tys[2] == elem_ty,
-                 "SIMD insert intrinsic monomorphized with inserted type not SIMD element type");
+        require!(in_elem == arg_tys[2],
+                 "expected inserted type `{}` (element of input `{}`), found `{}`",
+                 in_elem, in_ty, arg_tys[2]);
         return InsertElement(bcx, llargs[0], llargs[2], llargs[1])
     }
     if name == "simd_extract" {
-        require!(arg_tys[0].is_simd(),
-                 "SIMD insert intrinsic monomorphized for non-SIMD input type");
-
-        let elem_ty = arg_tys[0].simd_type(tcx);
-        require!(ret_ty == elem_ty,
-                 "SIMD insert intrinsic monomorphized with returned type not SIMD element type");
+        require!(ret_ty == in_elem,
+                 "expected return type `{}` (element of input `{}`), found `{}`",
+                 in_elem, in_ty, ret_ty);
         return ExtractElement(bcx, llargs[0], llargs[1])
     }
 
     if name == "simd_cast" {
-        require!(arg_tys[0].is_simd(),
-                 "SIMD cast intrinsic monomorphized with non-SIMD input type `{}`",
-                 arg_tys[0]);
-        require!(ret_ty.is_simd(),
-                 "SIMD cast intrinsic monomorphized with non-SIMD return type `{}`",
-                 ret_ty);
-        require!(arg_tys[0].simd_size(tcx) == ret_ty.simd_size(tcx),
-                 "SIMD cast intrinsic monomorphized with input type `{}` and \
-                  return type `{}` with different lengths: {} vs. {}",
-                 arg_tys[0],
-                 ret_ty,
-                 arg_tys[0].simd_size(tcx),
-                 ret_ty.simd_size(tcx));
+        require_simd!(ret_ty, "return");
+        let out_len = ret_ty.simd_size(tcx);
+        require!(in_len == out_len,
+                 "expected return type with length {} (same as input type `{}`), \
+                  found `{}` with length {}",
+                 in_len, in_ty,
+                 ret_ty, out_len);
         // casting cares about nominal type, not just structural type
-        let in_ = arg_tys[0].simd_type(tcx);
-        let out = ret_ty.simd_type(tcx);
+        let out_elem = ret_ty.simd_type(tcx);
 
-        if in_ == out { return llargs[0]; }
+        if in_elem == out_elem { return llargs[0]; }
 
-        match (&in_.sty, &out.sty) {
+        match (&in_elem.sty, &out_elem.sty) {
             (&ty::TyInt(lhs), &ty::TyInt(rhs)) => {
                 match (lhs, rhs) {
                     (ast::TyI8, ast::TyI8) |
@@ -1605,20 +1601,15 @@ macro_rules! require {
             _ => {}
         }
         require!(false,
-                 "SIMD cast intrinsic monomorphized with incompatible cast \
-                  from `{}` (element `{}`)to `{}` (element `{}`)",
-                 arg_tys[0], in_,
-                 ret_ty, out);
+                 "unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
+                 in_ty, in_elem,
+                 ret_ty, out_elem);
     }
     macro_rules! arith {
         ($($name: ident: $($($p: ident),* => $call: expr),*;)*) => {
             $(
                 if name == stringify!($name) {
-                    require!(arg_tys[0].is_simd(),
-                             "`{}` intrinsic monomorphized with non-SIMD type `{}`",
-                             name, arg_tys[0]);
-                    let in_ = arg_tys[0].simd_type(tcx);
-                    match in_.sty {
+                    match in_elem.sty {
                         $(
                             $(ty::$p(_))|* => {
                                 return $call(bcx, llargs[0], llargs[1], call_debug_location)
@@ -1627,11 +1618,9 @@ macro_rules! arith {
                         _ => {},
                     }
                     require!(false,
-                             "`{}` intrinsic monomorphized with SIMD vector `{}` \
-                              with unsupported element type `{}`",
-                             name,
-                             arg_tys[0],
-                             in_)
+                             "unsupported operation on `{}` with element `{}`",
+                             in_ty,
+                             in_elem)
                 })*
         }
     }
index d4fbcb41e2a91ba0eb5f8718e67fd64098d71940..35c368f4cbedb5bb399156b590bbc7ad1f43dfdd 100644 (file)
@@ -65,38 +65,38 @@ fn main() {
 
 
         simd_add(0, 0);
-        //~^ ERROR `simd_add` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_sub(0, 0);
-        //~^ ERROR `simd_sub` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_mul(0, 0);
-        //~^ ERROR `simd_mul` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_div(0, 0);
-        //~^ ERROR `simd_div` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shl(0, 0);
-        //~^ ERROR `simd_shl` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shr(0, 0);
-        //~^ ERROR `simd_shr` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_and(0, 0);
-        //~^ ERROR `simd_and` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_or(0, 0);
-        //~^ ERROR `simd_or` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_xor(0, 0);
-        //~^ ERROR `simd_xor` intrinsic monomorphized with non-SIMD type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
 
 
         simd_div(x, x);
-//~^ ERROR `simd_div` intrinsic monomorphized with SIMD vector `i32x4` with unsupported element type
+//~^ ERROR unsupported operation on `i32x4` with element `i32`
         simd_div(y, y);
-//~^ ERROR `simd_div` intrinsic monomorphized with SIMD vector `u32x4` with unsupported element type
+//~^ ERROR unsupported operation on `u32x4` with element `u32`
         simd_shl(z, z);
-//~^ ERROR `simd_shl` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_shr(z, z);
-//~^ ERROR `simd_shr` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_and(z, z);
-//~^ ERROR `simd_and` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_or(z, z);
-//~^ ERROR `simd_or` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
         simd_xor(z, z);
-//~^ ERROR `simd_xor` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
+//~^ ERROR unsupported operation on `f32x4` with element `f32`
     }
 }
index 333ef756e1fa5057aee89a95ff2f12ad966bf969..4999b790b130a4e79cb9b9e4ea63b001f0ef93d8 100644 (file)
@@ -40,12 +40,12 @@ fn main() {
 
     unsafe {
         simd_cast::<i32, i32>(0);
-        //~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD input type `i32`
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_cast::<i32, i32x4>(0);
-        //~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD input type `i32`
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_cast::<i32x4, i32>(x);
-        //~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD return type `i32`
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_cast::<_, i32x8>(x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i32x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
     }
 }
index 37827fbb6fbbb22955c1841c5e193e1702ba696b..617b03a87117b75b3ff97d26c88c1f1b9b6ca2e0 100644 (file)
@@ -34,42 +34,42 @@ fn main() {
 
     unsafe {
         simd_eq::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_ne::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_lt::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_le::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_gt::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_ge::<i32, i32>(0, 0);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
 
         simd_eq::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_ne::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_lt::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_le::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_gt::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
         simd_ge::<_, i32>(x, x);
-        //~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
+        //~^ ERROR expected SIMD return type, found non-SIMD `i32`
 
         simd_eq::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
         simd_ne::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
         simd_lt::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
         simd_le::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
         simd_gt::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
         simd_ge::<_, i16x8>(x, x);
-//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
+//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
     }
 }
index ebe442c1a2e4dee05045f81fd997a1f864da7556..b0198c411d5679ec1e06727969e619c9fe0fad78 100644 (file)
@@ -61,28 +61,37 @@ fn main() {
 
     unsafe {
         simd_insert(0, 0, 0);
-        //~^ ERROR SIMD insert intrinsic monomorphized for non-SIMD input type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_insert(x, 0, 1.0);
-        //~^ ERROR SIMD insert intrinsic monomorphized with inserted type not SIMD element type
+        //~^ ERROR expected inserted type `i32` (element of input `i32x4`), found `f64`
         simd_extract::<_, f32>(x, 0);
-        //~^ ERROR SIMD insert intrinsic monomorphized with returned type not SIMD element type
+        //~^ ERROR expected return type `i32` (element of input `i32x4`), found `f32`
 
         simd_shuffle2::<i32, i32>(0, 0, [0; 2]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with non-SIMD input type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shuffle3::<i32, i32>(0, 0, [0; 3]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with non-SIMD input type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shuffle4::<i32, i32>(0, 0, [0; 4]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with non-SIMD input type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
         simd_shuffle8::<i32, i32>(0, 0, [0; 8]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with non-SIMD input type
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
 
         simd_shuffle2::<_, f32x2>(x, x, [0; 2]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with different input and return element
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
         simd_shuffle3::<_, f32x3>(x, x, [0; 3]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with different input and return element
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x3` with element type `f32`
         simd_shuffle4::<_, f32x4>(x, x, [0; 4]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with different input and return element
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
         simd_shuffle8::<_, f32x8>(x, x, [0; 8]);
-        //~^ ERROR SIMD shuffle intrinsic monomorphized with different input and return element
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
+
+        simd_shuffle2::<_, i32x8>(x, x, [0; 2]);
+        //~^ ERROR expected return type of length 2, found `i32x8` with length 8
+        simd_shuffle3::<_, i32x4>(x, x, [0; 3]);
+        //~^ ERROR expected return type of length 3, found `i32x4` with length 4
+        simd_shuffle4::<_, i32x3>(x, x, [0; 4]);
+        //~^ ERROR expected return type of length 4, found `i32x3` with length 3
+        simd_shuffle8::<_, i32x2>(x, x, [0; 8]);
+        //~^ ERROR expected return type of length 8, found `i32x2` with length 2
     }
 }