提交 45fe3a1a 编写于 作者: A Ariel Ben-Yehuda

emit an assume that cast-from enums are in range

Fixes #36955.
上级 92333662
......@@ -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 @@ pub fn trans_rvalue_operand(&mut self,
}
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())
};
......
// 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]
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册