Add assume intrinsic

Adds an `assume` intrinsic that gets translated to llvm.assume. It is
used on a boolean expression and allows the optimizer to assume that
the expression is true.

This implements #18051.
This commit is contained in:
Viktor Dahl 2014-10-16 01:44:44 +02:00
parent e4761c85b5
commit 0525bb7669
5 changed files with 36 additions and 0 deletions

View File

@ -256,6 +256,13 @@ extern "rust-intrinsic" {
/// NB: This is very different from the `unreachable!()` macro!
pub fn unreachable() -> !;
/// Inform the optimizer that a condition is always true.
/// If the condition is false, the behavior is undefined.
///
/// No code is generated for this intrisic.
#[cfg(not(stage0))]
pub fn assume(b: bool);
/// Execute a breakpoint trap, for inspection by a debugger.
pub fn breakpoint();

View File

@ -855,6 +855,7 @@ fn declare_intrinsic(ccx: &CrateContext, key: & &'static str) -> Option<ValueRef
ifn!("llvm.lifetime.end" fn(t_i64, i8p) -> void);
ifn!("llvm.expect.i1" fn(i1, i1) -> i1);
ifn!("llvm.assume" fn(i1) -> void);
// Some intrinsics were introduced in later versions of LLVM, but they have
// fallbacks in libc or libm and such. Currently, all of these intrinsics

View File

@ -81,6 +81,7 @@ pub fn get_simple_intrinsic(ccx: &CrateContext, item: &ast::ForeignItem) -> Opti
"bswap16" => "llvm.bswap.i16",
"bswap32" => "llvm.bswap.i32",
"bswap64" => "llvm.bswap.i64",
"assume" => "llvm.assume",
_ => return None
};
Some(ccx.get_intrinsic(&name))

View File

@ -5754,6 +5754,8 @@ pub fn check_intrinsic_type(ccx: &CrateCtxt, it: &ast::ForeignItem) {
"return_address" => (0, vec![], ty::mk_imm_ptr(tcx, ty::mk_u8())),
"assume" => (0, vec![ty::mk_bool()], ty::mk_nil()),
ref other => {
span_err!(tcx.sess, it.span, E0093,
"unrecognized intrinsic function: `{}`", *other);

View File

@ -0,0 +1,25 @@
// Copyright 2014 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.
use std::intrinsics::assume;
unsafe fn f(x: i32) -> i32 {
assume(x == 34);
match x {
34 => 42,
_ => 30
}
}
fn main() {
let x = unsafe { f(34) };
assert_eq!(x, 42);
}