diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs index dda33ae3fec..7eac8e735ed 100644 --- a/src/librustc_codegen_llvm/mir/rvalue.rs +++ b/src/librustc_codegen_llvm/mir/rvalue.rs @@ -304,7 +304,9 @@ impl FunctionCx<'a, 'll, 'tcx> { // then `i1 1` (i.e. E::B) is effectively `i8 -1`. signed = !scalar.is_bool() && s; - if scalar.valid_range.end() > scalar.valid_range.start() { + let er = scalar.valid_range_exclusive(bx.cx); + if er.end != er.start && + scalar.valid_range.end() > scalar.valid_range.start() { // We want `table[e as usize]` to not // have bound checks, and this is the most // convenient place to put the `assume`. diff --git a/src/librustc_target/abi/mod.rs b/src/librustc_target/abi/mod.rs index 4f25360d8ea..16b5241b29a 100644 --- a/src/librustc_target/abi/mod.rs +++ b/src/librustc_target/abi/mod.rs @@ -596,7 +596,16 @@ pub struct Scalar { pub value: Primitive, /// Inclusive wrap-around range of valid values, that is, if - /// min > max, it represents min..=u128::MAX followed by 0..=max. + /// start > end, it represents `start..=max_value()`, + /// followed by `0..=end`. + /// + /// That is, for an i8 primitive, a range of `254..=2` means following + /// sequence: + /// + /// 254 (-2), 255 (-1), 0, 1, 2 + /// + /// This is intended specifically to mirror LLVM’s `!range` metadata, + /// semantics. // FIXME(eddyb) always use the shortest range, e.g. by finding // the largest space between two consecutive valid values and // taking everything else as the (shortest) valid range. diff --git a/src/test/codegen/no-assumes-on-casts.rs b/src/test/codegen/no-assumes-on-casts.rs new file mode 100644 index 00000000000..a5a7d94a553 --- /dev/null +++ b/src/test/codegen/no-assumes-on-casts.rs @@ -0,0 +1,29 @@ +// 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 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![crate_type = "lib"] + +// compile-flags: -Cno-prepopulate-passes + +// CHECK-LABEL: fna +#[no_mangle] +pub fn fna(a: i16) -> i32 { + a as i32 +// CHECK-NOT: assume +// CHECK: sext +} + +// CHECK-LABEL: fnb +#[no_mangle] +pub fn fnb(a: u16) -> u32 { + a as u32 +// CHECK-NOT: assume +// CHECK: zext +}