@@ -14,6 +14,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
1414use rustc_codegen_ssa:: traits:: * ;
1515use rustc_data_structures:: small_c_str:: SmallCStr ;
1616use rustc_hir:: def_id:: DefId ;
17+ use rustc_middle:: bug;
1718use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
1819use rustc_middle:: ty:: layout:: {
1920 FnAbiError , FnAbiOfHelpers , FnAbiRequest , HasTypingEnv , LayoutError , LayoutOfHelpers ,
@@ -1119,6 +1120,35 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
11191120 unsafe { llvm:: LLVMBuildFCmp ( self . llbuilder , op as c_uint , lhs, rhs, UNNAMED ) }
11201121 }
11211122
1123+ fn three_way_compare (
1124+ & mut self ,
1125+ ty : Ty < ' tcx > ,
1126+ lhs : Self :: Value ,
1127+ rhs : Self :: Value ,
1128+ ) -> Option < Self :: Value > {
1129+ // FIXME: See comment on the definition of `three_way_compare`.
1130+ if crate :: llvm_util:: get_version ( ) < ( 20 , 0 , 0 ) {
1131+ return None ;
1132+ }
1133+
1134+ let name = match ( ty. is_signed ( ) , ty. primitive_size ( self . tcx ) . bits ( ) ) {
1135+ ( true , 8 ) => "llvm.scmp.i8.i8" ,
1136+ ( true , 16 ) => "llvm.scmp.i8.i16" ,
1137+ ( true , 32 ) => "llvm.scmp.i8.i32" ,
1138+ ( true , 64 ) => "llvm.scmp.i8.i64" ,
1139+ ( true , 128 ) => "llvm.scmp.i8.i128" ,
1140+
1141+ ( false , 8 ) => "llvm.ucmp.i8.i8" ,
1142+ ( false , 16 ) => "llvm.ucmp.i8.i16" ,
1143+ ( false , 32 ) => "llvm.ucmp.i8.i32" ,
1144+ ( false , 64 ) => "llvm.ucmp.i8.i64" ,
1145+ ( false , 128 ) => "llvm.ucmp.i8.i128" ,
1146+
1147+ _ => bug ! ( "three-way compare unsupported for type {ty:?}" ) ,
1148+ } ;
1149+ Some ( self . call_intrinsic ( name, & [ lhs, rhs] ) )
1150+ }
1151+
11221152 /* Miscellaneous instructions */
11231153 fn memcpy (
11241154 & mut self ,
0 commit comments