@@ -12,6 +12,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1212use rustc_codegen_ssa:: traits:: * ;
1313use rustc_data_structures:: small_c_str:: SmallCStr ;
1414use rustc_hir:: def_id:: DefId ;
15+ use rustc_middle:: bug;
1516use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
1617use rustc_middle:: ty:: layout:: {
1718 FnAbiError , FnAbiOfHelpers , FnAbiRequest , HasTypingEnv , LayoutError , LayoutOfHelpers ,
@@ -873,6 +874,35 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
873874 unsafe { llvm:: LLVMBuildFCmp ( self . llbuilder , op as c_uint , lhs, rhs, UNNAMED ) }
874875 }
875876
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+
876906 /* Miscellaneous instructions */
877907 fn memcpy (
878908 & mut self ,
0 commit comments