Auto merge of #133984 - DaniPopes:scmp-ucmp, r=scottmcm
Lower BinOp::Cmp to llvm.{s,u}cmp.* intrinsics Lowers `mir::BinOp::Cmp` (`three_way_compare` intrinsic) to the corresponding LLVM `llvm.{s,u}cmp.i8.*` intrinsics. These are the intrinsics mentioned in https://github.com/rust-lang/rust/pull/118310, which are now available in LLVM 19. I couldn't find any follow-up PRs/discussions about this, please let me know if I missed something. r? `@scottmcm`
This commit is contained in:
commit
1df5affaca
8 changed files with 124 additions and 42 deletions
|
@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
|
|||
use rustc_codegen_ssa::traits::*;
|
||||
use rustc_data_structures::small_c_str::SmallCStr;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_middle::bug;
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
|
||||
use rustc_middle::ty::layout::{
|
||||
FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasTypingEnv, LayoutError, LayoutOfHelpers,
|
||||
|
@ -1074,6 +1075,35 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
|
|||
unsafe { llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED) }
|
||||
}
|
||||
|
||||
fn three_way_compare(
|
||||
&mut self,
|
||||
ty: Ty<'tcx>,
|
||||
lhs: Self::Value,
|
||||
rhs: Self::Value,
|
||||
) -> Option<Self::Value> {
|
||||
// FIXME: See comment on the definition of `three_way_compare`.
|
||||
if crate::llvm_util::get_version() < (20, 0, 0) {
|
||||
return None;
|
||||
}
|
||||
|
||||
let name = match (ty.is_signed(), ty.primitive_size(self.tcx).bits()) {
|
||||
(true, 8) => "llvm.scmp.i8.i8",
|
||||
(true, 16) => "llvm.scmp.i8.i16",
|
||||
(true, 32) => "llvm.scmp.i8.i32",
|
||||
(true, 64) => "llvm.scmp.i8.i64",
|
||||
(true, 128) => "llvm.scmp.i8.i128",
|
||||
|
||||
(false, 8) => "llvm.ucmp.i8.i8",
|
||||
(false, 16) => "llvm.ucmp.i8.i16",
|
||||
(false, 32) => "llvm.ucmp.i8.i32",
|
||||
(false, 64) => "llvm.ucmp.i8.i64",
|
||||
(false, 128) => "llvm.ucmp.i8.i128",
|
||||
|
||||
_ => bug!("three-way compare unsupported for type {ty:?}"),
|
||||
};
|
||||
Some(self.call_intrinsic(name, &[lhs, rhs]))
|
||||
}
|
||||
|
||||
/* Miscellaneous instructions */
|
||||
fn memcpy(
|
||||
&mut self,
|
||||
|
|
|
@ -1127,6 +1127,18 @@ impl<'ll> CodegenCx<'ll, '_> {
|
|||
ifn!("llvm.usub.sat.i64", fn(t_i64, t_i64) -> t_i64);
|
||||
ifn!("llvm.usub.sat.i128", fn(t_i128, t_i128) -> t_i128);
|
||||
|
||||
ifn!("llvm.scmp.i8.i8", fn(t_i8, t_i8) -> t_i8);
|
||||
ifn!("llvm.scmp.i8.i16", fn(t_i16, t_i16) -> t_i8);
|
||||
ifn!("llvm.scmp.i8.i32", fn(t_i32, t_i32) -> t_i8);
|
||||
ifn!("llvm.scmp.i8.i64", fn(t_i64, t_i64) -> t_i8);
|
||||
ifn!("llvm.scmp.i8.i128", fn(t_i128, t_i128) -> t_i8);
|
||||
|
||||
ifn!("llvm.ucmp.i8.i8", fn(t_i8, t_i8) -> t_i8);
|
||||
ifn!("llvm.ucmp.i8.i16", fn(t_i16, t_i16) -> t_i8);
|
||||
ifn!("llvm.ucmp.i8.i32", fn(t_i32, t_i32) -> t_i8);
|
||||
ifn!("llvm.ucmp.i8.i64", fn(t_i64, t_i64) -> t_i8);
|
||||
ifn!("llvm.ucmp.i8.i128", fn(t_i128, t_i128) -> t_i8);
|
||||
|
||||
ifn!("llvm.lifetime.start.p0i8", fn(t_i64, ptr) -> void);
|
||||
ifn!("llvm.lifetime.end.p0i8", fn(t_i64, ptr) -> void);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue