Generalized RealPredicate
This commit is contained in:
parent
51b7f2739b
commit
8590336d49
5 changed files with 62 additions and 16 deletions
|
@ -75,7 +75,7 @@ use rustc_data_structures::small_c_str::SmallCStr;
|
||||||
use rustc_data_structures::sync::Lrc;
|
use rustc_data_structures::sync::Lrc;
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
|
||||||
use traits::{IntPredicate, BuilderMethods};
|
use traits::{IntPredicate, RealPredicate, BuilderMethods};
|
||||||
use llvm::BasicBlock;
|
use llvm::BasicBlock;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
|
@ -143,14 +143,14 @@ pub fn bin_op_to_icmp_predicate(op: hir::BinOpKind,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate {
|
pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> RealPredicate {
|
||||||
match op {
|
match op {
|
||||||
hir::BinOpKind::Eq => llvm::RealOEQ,
|
hir::BinOpKind::Eq => RealPredicate::RealOEQ,
|
||||||
hir::BinOpKind::Ne => llvm::RealUNE,
|
hir::BinOpKind::Ne => RealPredicate::RealUNE,
|
||||||
hir::BinOpKind::Lt => llvm::RealOLT,
|
hir::BinOpKind::Lt => RealPredicate::RealOLT,
|
||||||
hir::BinOpKind::Le => llvm::RealOLE,
|
hir::BinOpKind::Le => RealPredicate::RealOLE,
|
||||||
hir::BinOpKind::Gt => llvm::RealOGT,
|
hir::BinOpKind::Gt => RealPredicate::RealOGT,
|
||||||
hir::BinOpKind::Ge => llvm::RealOGE,
|
hir::BinOpKind::Ge => RealPredicate::RealOGE,
|
||||||
op => {
|
op => {
|
||||||
bug!("comparison_op_to_fcmp_predicate: expected comparison operator, \
|
bug!("comparison_op_to_fcmp_predicate: expected comparison operator, \
|
||||||
found {:?}",
|
found {:?}",
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
|
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
|
||||||
use llvm::{RealPredicate, False, OperandBundleDef};
|
use llvm::{False, OperandBundleDef};
|
||||||
use llvm::{self, BasicBlock};
|
use llvm::{self, BasicBlock};
|
||||||
use common::*;
|
use common::*;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
@ -697,7 +697,7 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
fn fcmp(&self, op: traits::RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
|
||||||
self.count_insn("fcmp");
|
self.count_insn("fcmp");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
|
llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
|
||||||
|
|
|
@ -181,6 +181,29 @@ pub enum RealPredicate {
|
||||||
RealPredicateTrue = 15,
|
RealPredicateTrue = 15,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl traits::RealPredicateMethods for RealPredicate {
|
||||||
|
fn convert_to_backend_specific(realpred: traits::RealPredicate) -> Self {
|
||||||
|
match realpred {
|
||||||
|
traits::RealPredicate::RealPredicateFalse => RealPredicate::RealPredicateFalse,
|
||||||
|
traits::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
|
||||||
|
traits::RealPredicate::RealOGT => RealPredicate::RealOGT,
|
||||||
|
traits::RealPredicate::RealOGE => RealPredicate::RealOGE,
|
||||||
|
traits::RealPredicate::RealOLT => RealPredicate::RealOLT,
|
||||||
|
traits::RealPredicate::RealOLE => RealPredicate::RealOLE,
|
||||||
|
traits::RealPredicate::RealONE => RealPredicate::RealONE,
|
||||||
|
traits::RealPredicate::RealORD => RealPredicate::RealORD,
|
||||||
|
traits::RealPredicate::RealUNO => RealPredicate::RealUNO,
|
||||||
|
traits::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
|
||||||
|
traits::RealPredicate::RealUGT => RealPredicate::RealUGT,
|
||||||
|
traits::RealPredicate::RealUGE => RealPredicate::RealUGE,
|
||||||
|
traits::RealPredicate::RealULT => RealPredicate::RealULT,
|
||||||
|
traits::RealPredicate::RealULE => RealPredicate::RealULE,
|
||||||
|
traits::RealPredicate::RealUNE => RealPredicate::RealUNE,
|
||||||
|
traits::RealPredicate::RealPredicateTrue => RealPredicate::RealPredicateTrue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// LLVMTypeKind
|
/// LLVMTypeKind
|
||||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
// option. This file may not be copied, modified, or distributed
|
// option. This file may not be copied, modified, or distributed
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use llvm;
|
|
||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use rustc::ty::cast::{CastTy, IntTy};
|
use rustc::ty::cast::{CastTy, IntTy};
|
||||||
use rustc::ty::layout::{self, LayoutOf};
|
use rustc::ty::layout::{self, LayoutOf};
|
||||||
|
@ -28,7 +27,7 @@ use type_::Type;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
use traits::{IntPredicate,BuilderMethods};
|
use traits::{IntPredicate, RealPredicate, BuilderMethods};
|
||||||
|
|
||||||
use super::{FunctionCx, LocalRef};
|
use super::{FunctionCx, LocalRef};
|
||||||
use super::operand::{OperandRef, OperandValue};
|
use super::operand::{OperandRef, OperandValue};
|
||||||
|
@ -962,8 +961,8 @@ fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
// negation, and the negation can be merged into the select. Therefore, it not necessarily any
|
// negation, and the negation can be merged into the select. Therefore, it not necessarily any
|
||||||
// more expensive than a ordered ("normal") comparison. Whether these optimizations will be
|
// more expensive than a ordered ("normal") comparison. Whether these optimizations will be
|
||||||
// performed is ultimately up to the backend, but at least x86 does perform them.
|
// performed is ultimately up to the backend, but at least x86 does perform them.
|
||||||
let less_or_nan = bx.fcmp(llvm::RealULT, x, f_min);
|
let less_or_nan = bx.fcmp(RealPredicate::RealULT, x, f_min);
|
||||||
let greater = bx.fcmp(llvm::RealOGT, x, f_max);
|
let greater = bx.fcmp(RealPredicate::RealOGT, x, f_max);
|
||||||
let int_max = C_uint_big(int_ty, int_max(signed, int_ty));
|
let int_max = C_uint_big(int_ty, int_max(signed, int_ty));
|
||||||
let int_min = C_uint_big(int_ty, int_min(signed, int_ty) as u128);
|
let int_min = C_uint_big(int_ty, int_min(signed, int_ty) as u128);
|
||||||
let s0 = bx.select(less_or_nan, int_min, fptosui_result);
|
let s0 = bx.select(less_or_nan, int_min, fptosui_result);
|
||||||
|
@ -974,7 +973,7 @@ fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
// Therefore we only need to execute this step for signed integer types.
|
// Therefore we only need to execute this step for signed integer types.
|
||||||
if signed {
|
if signed {
|
||||||
// LLVM has no isNaN predicate, so we use (x == x) instead
|
// LLVM has no isNaN predicate, so we use (x == x) instead
|
||||||
bx.select(bx.fcmp(llvm::RealOEQ, x, x), s1, C_uint(int_ty, 0))
|
bx.select(bx.fcmp(RealPredicate::RealOEQ, x, x), s1, C_uint(int_ty, 0))
|
||||||
} else {
|
} else {
|
||||||
s1
|
s1
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
|
use llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
|
||||||
use llvm::{RealPredicate, OperandBundleDef};
|
use llvm::OperandBundleDef;
|
||||||
use common::*;
|
use common::*;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use libc::c_char;
|
use libc::c_char;
|
||||||
|
@ -38,6 +38,30 @@ pub trait IntPredicateMethods {
|
||||||
fn convert_to_backend_specific(intpre : IntPredicate) -> Self;
|
fn convert_to_backend_specific(intpre : IntPredicate) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub enum RealPredicate {
|
||||||
|
RealPredicateFalse,
|
||||||
|
RealOEQ,
|
||||||
|
RealOGT,
|
||||||
|
RealOGE,
|
||||||
|
RealOLT,
|
||||||
|
RealOLE,
|
||||||
|
RealONE,
|
||||||
|
RealORD,
|
||||||
|
RealUNO,
|
||||||
|
RealUEQ,
|
||||||
|
RealUGT,
|
||||||
|
RealUGE,
|
||||||
|
RealULT,
|
||||||
|
RealULE,
|
||||||
|
RealUNE,
|
||||||
|
RealPredicateTrue,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait RealPredicateMethods {
|
||||||
|
fn convert_to_backend_specific(realpred : RealPredicate) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll,
|
pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll,
|
||||||
Value : ?Sized,
|
Value : ?Sized,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue