parent
9233366271
commit
45fe3a1a2a
@ -522,6 +522,11 @@ pub fn need_invoke(bcx: Block) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn call_assume<'a, 'tcx>(b: &Builder<'a, 'tcx>, val: ValueRef) {
|
||||
let assume_intrinsic = b.ccx.get_intrinsic("llvm.assume");
|
||||
b.call(assume_intrinsic, &[val], None);
|
||||
}
|
||||
|
||||
/// Helper for loading values from memory. Does the necessary conversion if the in-memory type
|
||||
/// differs from the type used for SSA values. Also handles various special cases where the type
|
||||
/// gives us better information about what we are loading.
|
||||
|
@ -11,12 +11,14 @@
|
||||
use llvm::{self, ValueRef};
|
||||
use rustc::ty::{self, Ty};
|
||||
use rustc::ty::cast::{CastTy, IntTy};
|
||||
use rustc::ty::layout::Layout;
|
||||
use rustc::mir::repr as mir;
|
||||
|
||||
use asm;
|
||||
use base;
|
||||
use callee::Callee;
|
||||
use common::{self, val_ty, C_bool, C_null, C_uint, BlockAndBuilder, Result};
|
||||
use common::{C_integral};
|
||||
use debuginfo::DebugLoc;
|
||||
use adt;
|
||||
use machine;
|
||||
@ -282,7 +284,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
|
||||
}
|
||||
OperandValue::Pair(..) => bug!("Unexpected Pair operand")
|
||||
};
|
||||
(discr, adt::is_discr_signed(&l))
|
||||
let (signed, min, max) = match l {
|
||||
&Layout::CEnum { signed, min, max, .. } => {
|
||||
(signed, min, max)
|
||||
}
|
||||
_ => bug!("CEnum {:?} is not an enum", operand)
|
||||
};
|
||||
|
||||
if max > min {
|
||||
// We want `table[e as usize]` to not
|
||||
// have bound checks, and this is the most
|
||||
// convenient place to put the `assume`.
|
||||
|
||||
base::call_assume(&bcx, bcx.icmp(
|
||||
llvm::IntULE,
|
||||
discr,
|
||||
C_integral(common::val_ty(discr), max, false)
|
||||
))
|
||||
}
|
||||
|
||||
(discr, signed)
|
||||
} else {
|
||||
(operand.immediate(), operand.ty.is_signed())
|
||||
};
|
||||
|
24
src/test/codegen/enum-bounds-check.rs
Normal file
24
src/test/codegen/enum-bounds-check.rs
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright 2016 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-flags: -O
|
||||
|
||||
#![crate_type = "lib"]
|
||||
|
||||
pub enum Foo {
|
||||
A, B
|
||||
}
|
||||
|
||||
// CHECK-LABEL: @lookup
|
||||
#[no_mangle]
|
||||
pub fn lookup(buf: &[u8; 2], f: Foo) -> u8 {
|
||||
// CHECK-NOT: panic_bounds_check
|
||||
buf[f as usize]
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user