about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-08-18 14:35:42 +0000
committerbors <bors@rust-lang.org>2018-08-18 14:35:42 +0000
commita3ad012e2d33680d40b325258c0da532d0a884f3 (patch)
tree406f62e7d2674d407998b5b99a1ea13402270a27
parent7de3dea2b76786077ad51b31d167867e5ecdfdbc (diff)
parentdc02a6070f899b87249efa8c09bb2b90dbe94b0d (diff)
downloadrust-a3ad012e2d33680d40b325258c0da532d0a884f3.tar.gz
rust-a3ad012e2d33680d40b325258c0da532d0a884f3.zip
Auto merge of #53286 - nagisa:cast-assumes, r=eddyb
Do not generate assumes for plain integer casts

I gave up on making anything more elegant for now.

r? @eddyb
-rw-r--r--src/librustc_codegen_llvm/mir/rvalue.rs4
-rw-r--r--src/librustc_target/abi/mod.rs11
-rw-r--r--src/test/codegen/no-assumes-on-casts.rs29
3 files changed, 42 insertions, 2 deletions
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 <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.
+
+#![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
+}