Skip to content

Commit 5660db2

Browse files
committed
auto merge of #16970 : kmcallister/rust/llvm-unreachable, r=thestinger
I'm not sure how to add an automated test for this.
2 parents 3b8c528 + 675aa76 commit 5660db2

File tree

7 files changed

+93
-0
lines changed

7 files changed

+93
-0
lines changed

src/libcore/intrinsics.rs

+7
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ extern "rust-intrinsic" {
250250
/// Abort the execution of the process.
251251
pub fn abort() -> !;
252252

253+
/// Tell LLVM that this point in the code is not reachable,
254+
/// enabling further optimizations.
255+
///
256+
/// NB: This is very different from the `unreachable!()` macro!
257+
#[cfg(not(stage0))]
258+
pub fn unreachable() -> !;
259+
253260
/// Execute a breakpoint trap, for inspection by a debugger.
254261
pub fn breakpoint();
255262

src/librustc/middle/trans/intrinsic.rs

+4
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,10 @@ pub fn trans_intrinsic_call<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, node: ast::N
228228
Unreachable(bcx);
229229
v
230230
}
231+
(_, "unreachable") => {
232+
Unreachable(bcx);
233+
C_nil(ccx)
234+
}
231235
(_, "breakpoint") => {
232236
let llfn = ccx.get_intrinsic(&("llvm.debugtrap"));
233237
Call(bcx, llfn, [], None)

src/librustc/middle/typeck/check/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -5586,6 +5586,7 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
55865586
} else {
55875587
match name.get() {
55885588
"abort" => (0, Vec::new(), ty::mk_bot()),
5589+
"unreachable" => (0, Vec::new(), ty::mk_bot()),
55895590
"breakpoint" => (0, Vec::new(), ty::mk_nil()),
55905591
"size_of" |
55915592
"pref_align_of" | "min_align_of" => (1u, Vec::new(), ty::mk_uint()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-include ../tools.mk
2+
3+
ifndef IS_WINDOWS
4+
# The assembly for exit-unreachable.rs should be shorter because it's missing
5+
# (at minimum) a return instruction.
6+
7+
all:
8+
$(RUSTC) -O --emit asm exit-ret.rs
9+
$(RUSTC) -O --emit asm exit-unreachable.rs
10+
test `wc -l < $(TMPDIR)/exit-unreachable.s` -lt `wc -l < $(TMPDIR)/exit-ret.s`
11+
else
12+
# Because of Windows exception handling, the code is not necessarily any shorter.
13+
# https://github.com/llvm-mirror/llvm/commit/64b2297786f7fd6f5fa24cdd4db0298fbf211466
14+
all:
15+
endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(asm)]
12+
#![crate_type="lib"]
13+
14+
pub fn exit(n: uint) {
15+
unsafe {
16+
// Pretend this asm is an exit() syscall.
17+
asm!("" :: "r"(n) :: "volatile");
18+
// Can't actually reach this point, but rustc doesn't know that.
19+
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(asm)]
12+
#![crate_type="lib"]
13+
14+
use std::intrinsics;
15+
16+
pub fn exit(n: uint) -> ! {
17+
unsafe {
18+
// Pretend this asm is an exit() syscall.
19+
asm!("" :: "r"(n) :: "volatile");
20+
intrinsics::unreachable()
21+
}
22+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::intrinsics;
12+
13+
// See also src/test/run-make/intrinsic-unreachable.
14+
15+
unsafe fn f(x: uint) -> uint {
16+
match x {
17+
17 => 23,
18+
_ => intrinsics::unreachable(),
19+
}
20+
}
21+
22+
fn main() {
23+
assert_eq!(unsafe { f(17) }, 23);
24+
}

0 commit comments

Comments
 (0)