Add+Use mir::BinOp::Cmp
This commit is contained in:
parent
744c664ba2
commit
3da115a93b
35 changed files with 521 additions and 119 deletions
|
@ -7,6 +7,7 @@ use crate::common::{self, IntPredicate};
|
|||
use crate::traits::*;
|
||||
use crate::MemFlags;
|
||||
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::mir::Operand;
|
||||
use rustc_middle::ty::cast::{CastTy, IntTy};
|
||||
|
@ -882,6 +883,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||
bx.icmp(base::bin_op_to_icmp_predicate(op.to_hir_binop(), is_signed), lhs, rhs)
|
||||
}
|
||||
}
|
||||
mir::BinOp::Cmp => {
|
||||
use std::cmp::Ordering;
|
||||
debug_assert!(!is_float);
|
||||
let pred = |op| base::bin_op_to_icmp_predicate(op, is_signed);
|
||||
if bx.cx().tcx().sess.opts.optimize == OptLevel::No {
|
||||
// FIXME: This actually generates tighter assembly, and is a classic trick
|
||||
// <https://graphics.stanford.edu/~seander/bithacks.html#CopyIntegerSign>
|
||||
// However, as of 2023-11 it optimizes worse in things like derived
|
||||
// `PartialOrd`, so only use it in debug for now. Once LLVM can handle it
|
||||
// better (see <https://github.com/llvm/llvm-project/issues/73417>), it'll
|
||||
// be worth trying it in optimized builds as well.
|
||||
let is_gt = bx.icmp(pred(hir::BinOpKind::Gt), lhs, rhs);
|
||||
let gtext = bx.zext(is_gt, bx.type_i8());
|
||||
let is_lt = bx.icmp(pred(hir::BinOpKind::Lt), lhs, rhs);
|
||||
let ltext = bx.zext(is_lt, bx.type_i8());
|
||||
bx.unchecked_ssub(gtext, ltext)
|
||||
} else {
|
||||
// These operations are those expected by `tests/codegen/integer-cmp.rs`,
|
||||
// from <https://github.com/rust-lang/rust/pull/63767>.
|
||||
let is_lt = bx.icmp(pred(hir::BinOpKind::Lt), lhs, rhs);
|
||||
let is_ne = bx.icmp(pred(hir::BinOpKind::Ne), lhs, rhs);
|
||||
let ge = bx.select(
|
||||
is_ne,
|
||||
bx.cx().const_i8(Ordering::Greater as i8),
|
||||
bx.cx().const_i8(Ordering::Equal as i8),
|
||||
);
|
||||
bx.select(is_lt, bx.cx().const_i8(Ordering::Less as i8), ge)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ pub trait ConstMethods<'tcx>: BackendTypes {
|
|||
fn const_bool(&self, val: bool) -> Self::Value;
|
||||
fn const_i16(&self, i: i16) -> Self::Value;
|
||||
fn const_i32(&self, i: i32) -> Self::Value;
|
||||
fn const_i8(&self, i: i8) -> Self::Value;
|
||||
fn const_u32(&self, i: u32) -> Self::Value;
|
||||
fn const_u64(&self, i: u64) -> Self::Value;
|
||||
fn const_u128(&self, i: u128) -> Self::Value;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue