Skip to content

Commit 502f9ac

Browse files
committed
Revamp SIMD intrinsic trans error handling.
Factor out common pieces, follow `expected ..., found ...` convention everywhere.
1 parent 891c914 commit 502f9ac

File tree

5 files changed

+129
-131
lines changed

5 files changed

+129
-131
lines changed

src/librustc_trans/trans/intrinsic.rs

+71-82
Original file line numberDiff line numberDiff line change
@@ -1329,14 +1329,33 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
13291329
call_debug_location: DebugLoc,
13301330
call_info: NodeIdAndSpan) -> ValueRef
13311331
{
1332+
// macros for error handling:
1333+
macro_rules! emit_error {
1334+
($msg: tt) => {
1335+
emit_error!($msg, )
1336+
};
1337+
($msg: tt, $($fmt: tt)*) => {
1338+
bcx.sess().span_err(call_info.span,
1339+
&format!(concat!("invalid monomorphization of `{}` intrinsic: ",
1340+
$msg),
1341+
name, $($fmt)*));
1342+
}
1343+
}
13321344
macro_rules! require {
13331345
($cond: expr, $($fmt: tt)*) => {
13341346
if !$cond {
1335-
bcx.sess().span_err(call_info.span, &format!($($fmt)*));
1347+
emit_error!($($fmt)*);
13361348
return C_null(llret_ty)
13371349
}
13381350
}
13391351
}
1352+
macro_rules! require_simd {
1353+
($ty: expr, $position: expr) => {
1354+
require!($ty.is_simd(), "expected SIMD {} type, found non-SIMD `{}`", $position, $ty)
1355+
}
1356+
}
1357+
1358+
13401359

13411360
let tcx = bcx.tcx();
13421361
let arg_tys = match callee_ty.sty {
@@ -1346,6 +1365,12 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
13461365
_ => unreachable!()
13471366
};
13481367

1368+
// every intrinsic takes a SIMD vector as its first argument
1369+
require_simd!(arg_tys[0], "input");
1370+
let in_ty = arg_tys[0];
1371+
let in_elem = arg_tys[0].simd_type(tcx);
1372+
let in_len = arg_tys[0].simd_size(tcx);
1373+
13491374
let comparison = match name {
13501375
"simd_eq" => Some(ast::BiEq),
13511376
"simd_ne" => Some(ast::BiNe),
@@ -1357,30 +1382,23 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
13571382
};
13581383

13591384
if let Some(cmp_op) = comparison {
1360-
assert_eq!(arg_tys.len(), 2);
1361-
require!(arg_tys[0].is_simd(),
1362-
"SIMD comparison intrinsic monomorphized for non-SIMD argument type `{}`",
1363-
arg_tys[0]);
1364-
require!(ret_ty.is_simd(),
1365-
"SIMD comparison intrinsic monomorphized for non-SIMD return type `{}`",
1366-
ret_ty);
1367-
1368-
let in_len = arg_tys[0].simd_size(tcx);
1385+
require_simd!(ret_ty, "return");
1386+
13691387
let out_len = ret_ty.simd_size(tcx);
13701388
require!(in_len == out_len,
1371-
"SIMD cast intrinsic monomorphized with input type `{}` and \
1372-
return type `{}` with different lengths: {} vs. {}",
1373-
arg_tys[0],
1374-
ret_ty,
1375-
in_len,
1376-
out_len);
1389+
"expected return type with length {} (same as input type `{}`), \
1390+
found `{}` with length {}",
1391+
in_len, in_ty,
1392+
ret_ty, out_len);
13771393
require!(llret_ty.element_type().kind() == llvm::Integer,
1378-
"SIMD comparison intrinsic monomorphized with non-integer return");
1394+
"expected return type with integer elements, found `{}` with non-integer `{}`",
1395+
ret_ty,
1396+
ret_ty.simd_type(tcx));
13791397

13801398
return compare_simd_types(bcx,
13811399
llargs[0],
13821400
llargs[1],
1383-
arg_tys[0].simd_type(tcx),
1401+
in_elem,
13841402
llret_ty,
13851403
cmp_op,
13861404
call_debug_location)
@@ -1390,24 +1408,20 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
13901408
let n: usize = match name["simd_shuffle".len()..].parse() {
13911409
Ok(n) => n,
13921410
Err(_) => tcx.sess.span_bug(call_info.span,
1393-
"bad `simd_shuffle` instruction only caught in trans?")
1411+
"bad `simd_shuffle` instruction only caught in trans?")
13941412
};
13951413

1396-
require!(arg_tys[0].is_simd(),
1397-
"SIMD shuffle intrinsic monomorphized with non-SIMD input type `{}`",
1398-
arg_tys[0]);
1399-
require!(ret_ty.is_simd(),
1400-
"SIMD shuffle intrinsic monomorphized for non-SIMD return type `{}`",
1401-
ret_ty);
1414+
require_simd!(ret_ty, "return");
14021415

1403-
let in_len = arg_tys[0].simd_size(tcx);
14041416
let out_len = ret_ty.simd_size(tcx);
14051417
require!(out_len == n,
1406-
"SIMD shuffle intrinsic monomorphized with return type of length {} (expected {})",
1407-
out_len, n);
1408-
require!(arg_tys[0].simd_type(tcx) == ret_ty.simd_type(tcx),
1409-
"SIMD shuffle intrinsic monomorphized with different \
1410-
input and return element types");
1418+
"expected return type of length {}, found `{}` with length {}",
1419+
n, ret_ty, out_len);
1420+
require!(in_elem == ret_ty.simd_type(tcx),
1421+
"expected return element type `{}` (element of input `{}`), \
1422+
found `{}` with element type `{}`",
1423+
in_elem, in_ty,
1424+
ret_ty, ret_ty.simd_type(tcx));
14111425

14121426
let total_len = in_len as u64 * 2;
14131427

@@ -1425,17 +1439,12 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
14251439
let c = const_to_opt_uint(val);
14261440
match c {
14271441
None => {
1428-
bcx.sess().span_err(call_info.span,
1429-
&format!("SIMD shuffle intrinsic argument #{} \
1430-
is not a constant",
1431-
arg_idx));
1442+
emit_error!("shuffle index #{} is not a constant", arg_idx);
14321443
None
14331444
}
14341445
Some(idx) if idx >= total_len => {
1435-
bcx.sess().span_err(call_info.span,
1436-
&format!("SIMD shuffle intrinsic argument #{} \
1437-
is out of bounds (limit {})",
1438-
arg_idx, total_len));
1446+
emit_error!("shuffle index #{} is out of bounds (limit {})",
1447+
arg_idx, total_len);
14391448
None
14401449
}
14411450
Some(idx) => Some(C_i32(bcx.ccx(), idx as i32)),
@@ -1451,45 +1460,32 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
14511460
}
14521461

14531462
if name == "simd_insert" {
1454-
require!(arg_tys[0].is_simd(),
1455-
"SIMD insert intrinsic monomorphized for non-SIMD input type");
1456-
1457-
let elem_ty = arg_tys[0].simd_type(tcx);
1458-
require!(arg_tys[2] == elem_ty,
1459-
"SIMD insert intrinsic monomorphized with inserted type not SIMD element type");
1463+
require!(in_elem == arg_tys[2],
1464+
"expected inserted type `{}` (element of input `{}`), found `{}`",
1465+
in_elem, in_ty, arg_tys[2]);
14601466
return InsertElement(bcx, llargs[0], llargs[2], llargs[1])
14611467
}
14621468
if name == "simd_extract" {
1463-
require!(arg_tys[0].is_simd(),
1464-
"SIMD insert intrinsic monomorphized for non-SIMD input type");
1465-
1466-
let elem_ty = arg_tys[0].simd_type(tcx);
1467-
require!(ret_ty == elem_ty,
1468-
"SIMD insert intrinsic monomorphized with returned type not SIMD element type");
1469+
require!(ret_ty == in_elem,
1470+
"expected return type `{}` (element of input `{}`), found `{}`",
1471+
in_elem, in_ty, ret_ty);
14691472
return ExtractElement(bcx, llargs[0], llargs[1])
14701473
}
14711474

14721475
if name == "simd_cast" {
1473-
require!(arg_tys[0].is_simd(),
1474-
"SIMD cast intrinsic monomorphized with non-SIMD input type `{}`",
1475-
arg_tys[0]);
1476-
require!(ret_ty.is_simd(),
1477-
"SIMD cast intrinsic monomorphized with non-SIMD return type `{}`",
1478-
ret_ty);
1479-
require!(arg_tys[0].simd_size(tcx) == ret_ty.simd_size(tcx),
1480-
"SIMD cast intrinsic monomorphized with input type `{}` and \
1481-
return type `{}` with different lengths: {} vs. {}",
1482-
arg_tys[0],
1483-
ret_ty,
1484-
arg_tys[0].simd_size(tcx),
1485-
ret_ty.simd_size(tcx));
1476+
require_simd!(ret_ty, "return");
1477+
let out_len = ret_ty.simd_size(tcx);
1478+
require!(in_len == out_len,
1479+
"expected return type with length {} (same as input type `{}`), \
1480+
found `{}` with length {}",
1481+
in_len, in_ty,
1482+
ret_ty, out_len);
14861483
// casting cares about nominal type, not just structural type
1487-
let in_ = arg_tys[0].simd_type(tcx);
1488-
let out = ret_ty.simd_type(tcx);
1484+
let out_elem = ret_ty.simd_type(tcx);
14891485

1490-
if in_ == out { return llargs[0]; }
1486+
if in_elem == out_elem { return llargs[0]; }
14911487

1492-
match (&in_.sty, &out.sty) {
1488+
match (&in_elem.sty, &out_elem.sty) {
14931489
(&ty::TyInt(lhs), &ty::TyInt(rhs)) => {
14941490
match (lhs, rhs) {
14951491
(ast::TyI8, ast::TyI8) |
@@ -1605,20 +1601,15 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
16051601
_ => {}
16061602
}
16071603
require!(false,
1608-
"SIMD cast intrinsic monomorphized with incompatible cast \
1609-
from `{}` (element `{}`)to `{}` (element `{}`)",
1610-
arg_tys[0], in_,
1611-
ret_ty, out);
1604+
"unsupported cast from `{}` with element `{}` to `{}` with element `{}`",
1605+
in_ty, in_elem,
1606+
ret_ty, out_elem);
16121607
}
16131608
macro_rules! arith {
16141609
($($name: ident: $($($p: ident),* => $call: expr),*;)*) => {
16151610
$(
16161611
if name == stringify!($name) {
1617-
require!(arg_tys[0].is_simd(),
1618-
"`{}` intrinsic monomorphized with non-SIMD type `{}`",
1619-
name, arg_tys[0]);
1620-
let in_ = arg_tys[0].simd_type(tcx);
1621-
match in_.sty {
1612+
match in_elem.sty {
16221613
$(
16231614
$(ty::$p(_))|* => {
16241615
return $call(bcx, llargs[0], llargs[1], call_debug_location)
@@ -1627,11 +1618,9 @@ fn generic_simd_intrinsic<'blk, 'tcx, 'a>
16271618
_ => {},
16281619
}
16291620
require!(false,
1630-
"`{}` intrinsic monomorphized with SIMD vector `{}` \
1631-
with unsupported element type `{}`",
1632-
name,
1633-
arg_tys[0],
1634-
in_)
1621+
"unsupported operation on `{}` with element `{}`",
1622+
in_ty,
1623+
in_elem)
16351624
})*
16361625
}
16371626
}

src/test/compile-fail/simd-intrinsic-generic-arithmetic.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -65,38 +65,38 @@ fn main() {
6565

6666

6767
simd_add(0, 0);
68-
//~^ ERROR `simd_add` intrinsic monomorphized with non-SIMD type
68+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
6969
simd_sub(0, 0);
70-
//~^ ERROR `simd_sub` intrinsic monomorphized with non-SIMD type
70+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7171
simd_mul(0, 0);
72-
//~^ ERROR `simd_mul` intrinsic monomorphized with non-SIMD type
72+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7373
simd_div(0, 0);
74-
//~^ ERROR `simd_div` intrinsic monomorphized with non-SIMD type
74+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7575
simd_shl(0, 0);
76-
//~^ ERROR `simd_shl` intrinsic monomorphized with non-SIMD type
76+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7777
simd_shr(0, 0);
78-
//~^ ERROR `simd_shr` intrinsic monomorphized with non-SIMD type
78+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
7979
simd_and(0, 0);
80-
//~^ ERROR `simd_and` intrinsic monomorphized with non-SIMD type
80+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
8181
simd_or(0, 0);
82-
//~^ ERROR `simd_or` intrinsic monomorphized with non-SIMD type
82+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
8383
simd_xor(0, 0);
84-
//~^ ERROR `simd_xor` intrinsic monomorphized with non-SIMD type
84+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
8585

8686

8787
simd_div(x, x);
88-
//~^ ERROR `simd_div` intrinsic monomorphized with SIMD vector `i32x4` with unsupported element type
88+
//~^ ERROR unsupported operation on `i32x4` with element `i32`
8989
simd_div(y, y);
90-
//~^ ERROR `simd_div` intrinsic monomorphized with SIMD vector `u32x4` with unsupported element type
90+
//~^ ERROR unsupported operation on `u32x4` with element `u32`
9191
simd_shl(z, z);
92-
//~^ ERROR `simd_shl` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
92+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
9393
simd_shr(z, z);
94-
//~^ ERROR `simd_shr` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
94+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
9595
simd_and(z, z);
96-
//~^ ERROR `simd_and` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
96+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
9797
simd_or(z, z);
98-
//~^ ERROR `simd_or` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
98+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
9999
simd_xor(z, z);
100-
//~^ ERROR `simd_xor` intrinsic monomorphized with SIMD vector `f32x4` with unsupported element type
100+
//~^ ERROR unsupported operation on `f32x4` with element `f32`
101101
}
102102
}

src/test/compile-fail/simd-intrinsic-generic-cast.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ fn main() {
4040

4141
unsafe {
4242
simd_cast::<i32, i32>(0);
43-
//~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD input type `i32`
43+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4444
simd_cast::<i32, i32x4>(0);
45-
//~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD input type `i32`
45+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4646
simd_cast::<i32x4, i32>(x);
47-
//~^ ERROR SIMD cast intrinsic monomorphized with non-SIMD return type `i32`
47+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
4848
simd_cast::<_, i32x8>(x);
49-
//~^ ERROR monomorphized with input type `i32x4` and return type `i32x8` with different lengths
49+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
5050
}
5151
}

src/test/compile-fail/simd-intrinsic-generic-comparison.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -34,42 +34,42 @@ fn main() {
3434

3535
unsafe {
3636
simd_eq::<i32, i32>(0, 0);
37-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
37+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
3838
simd_ne::<i32, i32>(0, 0);
39-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
39+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4040
simd_lt::<i32, i32>(0, 0);
41-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
41+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4242
simd_le::<i32, i32>(0, 0);
43-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
43+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4444
simd_gt::<i32, i32>(0, 0);
45-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
45+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4646
simd_ge::<i32, i32>(0, 0);
47-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD argument type
47+
//~^ ERROR expected SIMD input type, found non-SIMD `i32`
4848

4949
simd_eq::<_, i32>(x, x);
50-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
50+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
5151
simd_ne::<_, i32>(x, x);
52-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
52+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
5353
simd_lt::<_, i32>(x, x);
54-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
54+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
5555
simd_le::<_, i32>(x, x);
56-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
56+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
5757
simd_gt::<_, i32>(x, x);
58-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
58+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
5959
simd_ge::<_, i32>(x, x);
60-
//~^ ERROR SIMD comparison intrinsic monomorphized for non-SIMD return type
60+
//~^ ERROR expected SIMD return type, found non-SIMD `i32`
6161

6262
simd_eq::<_, i16x8>(x, x);
63-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
63+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
6464
simd_ne::<_, i16x8>(x, x);
65-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
65+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
6666
simd_lt::<_, i16x8>(x, x);
67-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
67+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
6868
simd_le::<_, i16x8>(x, x);
69-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
69+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
7070
simd_gt::<_, i16x8>(x, x);
71-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
71+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
7272
simd_ge::<_, i16x8>(x, x);
73-
//~^ ERROR monomorphized with input type `i32x4` and return type `i16x8` with different lengths
73+
//~^ ERROR return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
7474
}
7575
}

0 commit comments

Comments
 (0)