diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs
index 6f8b1f8e79940..ff7b4f9e0fd70 100644
--- a/src/librustc_mir/hair/pattern/_match.rs
+++ b/src/librustc_mir/hair/pattern/_match.rs
@@ -985,15 +985,17 @@ fn slice_pat_covered_by_constructor(tcx: TyCtxt, _span: Span,
     Ok(true)
 }
 
-fn constructor_covered_by_range(ctor: &Constructor,
-                                from: &ConstVal, to: &ConstVal,
-                                end: RangeEnd,
-                                ty: Ty)
-                                -> Result<bool, ErrorReported> {
+fn constructor_covered_by_range<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    ctor: &Constructor,
+    from: &ConstVal, to: &ConstVal,
+    end: RangeEnd,
+    ty: Ty<'tcx>,
+) -> Result<bool, ErrorReported> {
     trace!("constructor_covered_by_range {:#?}, {:#?}, {:#?}, {}", ctor, from, to, ty);
-    let cmp_from = |c_from| compare_const_vals(c_from, from, ty)
+    let cmp_from = |c_from| compare_const_vals(tcx, c_from, from, ty)
         .map(|res| res != Ordering::Less);
-    let cmp_to = |c_to| compare_const_vals(c_to, to, ty);
+    let cmp_to = |c_to| compare_const_vals(tcx, c_to, to, ty);
     macro_rules! some_or_ok {
         ($e:expr) => {
             match $e {
@@ -1105,6 +1107,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
                 },
                 _ => {
                     match constructor_covered_by_range(
+                        cx.tcx,
                         constructor, &value.val, &value.val, RangeEnd::Included,
                         value.ty,
                             ) {
@@ -1118,6 +1121,7 @@ fn specialize<'p, 'a: 'p, 'tcx: 'a>(
 
         PatternKind::Range { lo, hi, ref end } => {
             match constructor_covered_by_range(
+                cx.tcx,
                 constructor, &lo.val, &hi.val, end.clone(), lo.ty,
             ) {
                 Ok(true) => Some(vec![]),
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 8d2b73d6ba033..9f17af8b16f1d 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -16,7 +16,7 @@ mod check_match;
 pub use self::check_match::check_crate;
 pub(crate) use self::check_match::check_match;
 
-use interpret::{const_val_field, const_discr};
+use interpret::{const_val_field, const_discr, self};
 
 use rustc::middle::const_val::ConstVal;
 use rustc::mir::{Field, BorrowKind, Mutability};
@@ -372,7 +372,7 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                     (PatternKind::Constant { value: lo },
                      PatternKind::Constant { value: hi }) => {
                         use std::cmp::Ordering;
-                        match (end, compare_const_vals(&lo.val, &hi.val, ty).unwrap()) {
+                        match (end, compare_const_vals(self.tcx, &lo.val, &hi.val, ty).unwrap()) {
                             (RangeEnd::Excluded, Ordering::Less) =>
                                 PatternKind::Range { lo, hi, end },
                             (RangeEnd::Excluded, _) => {
@@ -1076,7 +1076,12 @@ impl<'tcx> PatternFoldable<'tcx> for PatternKind<'tcx> {
     }
 }
 
-pub fn compare_const_vals(a: &ConstVal, b: &ConstVal, ty: Ty) -> Option<Ordering> {
+pub fn compare_const_vals<'a, 'tcx>(
+    tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    a: &ConstVal,
+    b: &ConstVal,
+    ty: Ty<'tcx>,
+) -> Option<Ordering> {
     use rustc_const_math::ConstFloat;
     trace!("compare_const_vals: {:?}, {:?}", a, b);
     use rustc::mir::interpret::{Value, PrimVal};
@@ -1096,7 +1101,11 @@ pub fn compare_const_vals(a: &ConstVal, b: &ConstVal, ty: Ty) -> Option<Ordering
                     // FIXME(oli-obk): report cmp errors?
                     l.try_cmp(r).ok()
                 },
-                ty::TyInt(_) => Some((a as i128).cmp(&(b as i128))),
+                ty::TyInt(_) => {
+                    let a = interpret::sign_extend(tcx, a, ty).expect("layout error for TyInt");
+                    let b = interpret::sign_extend(tcx, b, ty).expect("layout error for TyInt");
+                    Some((a as i128).cmp(&(b as i128)))
+                },
                 _ => Some(a.cmp(&b)),
             }
         },
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index 03785f9623b8c..c5ff14e606968 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -1679,21 +1679,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
     }
 
     pub fn sign_extend(&self, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
-        let layout = self.layout_of(ty)?;
-        let size = layout.size.bits();
-        assert!(layout.abi.is_signed());
-        // sign extend
-        let amt = 128 - size;
-        // shift the unsigned value to the left
-        // and back to the right as signed (essentially fills with FF on the left)
-        Ok((((value << amt) as i128) >> amt) as u128)
+        super::sign_extend(self.tcx.tcx, value, ty)
     }
 
     pub fn truncate(&self, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
-        let size = self.layout_of(ty)?.size.bits();
-        let amt = 128 - size;
-        // truncate (shift left to drop out leftover values, shift right to fill with zeroes)
-        Ok((value << amt) >> amt)
+        super::truncate(self.tcx.tcx, value, ty)
     }
 }
 
diff --git a/src/librustc_mir/interpret/mod.rs b/src/librustc_mir/interpret/mod.rs
index ae6337d82c3e3..147db3bdc0e7a 100644
--- a/src/librustc_mir/interpret/mod.rs
+++ b/src/librustc_mir/interpret/mod.rs
@@ -31,3 +31,27 @@ pub use self::const_eval::{
 pub use self::machine::Machine;
 
 pub use self::memory::{write_target_uint, write_target_int, read_target_uint};
+
+use rustc::mir::interpret::{EvalResult, EvalErrorKind};
+use rustc::ty::{Ty, TyCtxt, ParamEnv};
+
+pub fn sign_extend<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
+    let param_env = ParamEnv::empty();
+    let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
+    let size = layout.size.bits();
+    assert!(layout.abi.is_signed());
+    // sign extend
+    let amt = 128 - size;
+    // shift the unsigned value to the left
+    // and back to the right as signed (essentially fills with FF on the left)
+    Ok((((value << amt) as i128) >> amt) as u128)
+}
+
+pub fn truncate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, value: u128, ty: Ty<'tcx>) -> EvalResult<'tcx, u128> {
+    let param_env = ParamEnv::empty();
+    let layout = tcx.layout_of(param_env.and(ty)).map_err(|layout| EvalErrorKind::Layout(layout))?;
+    let size = layout.size.bits();
+    let amt = 128 - size;
+    // truncate (shift left to drop out leftover values, shift right to fill with zeroes)
+    Ok((value << amt) >> amt)
+}
diff --git a/src/test/ui/const-eval/const_signed_pat.rs b/src/test/ui/const-eval/const_signed_pat.rs
new file mode 100644
index 0000000000000..f53d6f3fa0a15
--- /dev/null
+++ b/src/test/ui/const-eval/const_signed_pat.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-pass
+
+fn main() {
+    const MIN: i8 = -5;
+    match 5i8 {
+        MIN...-1 => {},
+        _ => {},
+    }
+}