@@ -12,6 +12,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
12
12
use rustc_codegen_ssa:: traits:: * ;
13
13
use rustc_data_structures:: small_c_str:: SmallCStr ;
14
14
use rustc_hir:: def_id:: DefId ;
15
+ use rustc_middle:: bug;
15
16
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
16
17
use rustc_middle:: ty:: layout:: {
17
18
FnAbiError , FnAbiOfHelpers , FnAbiRequest , HasTypingEnv , LayoutError , LayoutOfHelpers ,
@@ -873,6 +874,35 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
873
874
unsafe { llvm:: LLVMBuildFCmp ( self . llbuilder , op as c_uint , lhs, rhs, UNNAMED ) }
874
875
}
875
876
877
+ fn three_way_compare (
878
+ & mut self ,
879
+ ty : Ty < ' tcx > ,
880
+ lhs : Self :: Value ,
881
+ rhs : Self :: Value ,
882
+ ) -> Option < Self :: Value > {
883
+ // FIXME: See comment on the definition of `three_way_compare`.
884
+ if crate :: llvm_util:: get_version ( ) < ( 20 , 0 , 0 ) {
885
+ return None ;
886
+ }
887
+
888
+ let name = match ( ty. is_signed ( ) , ty. primitive_size ( self . tcx ) . bits ( ) ) {
889
+ ( true , 8 ) => "llvm.scmp.i8.i8" ,
890
+ ( true , 16 ) => "llvm.scmp.i8.i16" ,
891
+ ( true , 32 ) => "llvm.scmp.i8.i32" ,
892
+ ( true , 64 ) => "llvm.scmp.i8.i64" ,
893
+ ( true , 128 ) => "llvm.scmp.i8.i128" ,
894
+
895
+ ( false , 8 ) => "llvm.ucmp.i8.i8" ,
896
+ ( false , 16 ) => "llvm.ucmp.i8.i16" ,
897
+ ( false , 32 ) => "llvm.ucmp.i8.i32" ,
898
+ ( false , 64 ) => "llvm.ucmp.i8.i64" ,
899
+ ( false , 128 ) => "llvm.ucmp.i8.i128" ,
900
+
901
+ _ => bug ! ( "three-way compare unsupported for type {ty:?}" ) ,
902
+ } ;
903
+ Some ( self . call_intrinsic ( name, & [ lhs, rhs] ) )
904
+ }
905
+
876
906
/* Miscellaneous instructions */
877
907
fn memcpy (
878
908
& mut self ,
0 commit comments